From 521993214708c66a5498bd669c94a661c11484b2 Mon Sep 17 00:00:00 2001
From: IT-KIMI_SHI\SINOIT.KIMI <kimi42345@gmail.com>
Date: 星期五, 01 六月 2018 15:42:59 +0800
Subject: [PATCH] init

---
 .metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.derby.prefs                    |    3 
 src/frame/expression/VariantExistsException.java                                                          |   11 
 src/frame/file/UploadResult.java                                                                          |  151 
 src/frame/schedule/Job.java                                                                               |   82 
 src/frame/persist/SQLCreator.java                                                                         |   96 
 src/frame/data/convert/BigDecimalTranslator.java                                                          |  128 
 .metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml                                                 |   10 
 src/frame/object/http/HttpDataPool.java                                                                   |   25 
 src/frame/persist/loader/ValueLoader.java                                                                 |   46 
 src/frame/data/reader/EntityReader.java                                                                   |   76 
 src/frame/file/office/ExcelHandler.java                                                                   |  474 +
 src/frame/data/reader/CollectionReader.java                                                               |  103 
 src/frame/expression/Expression.java                                                                      |  154 
 src/frame/file/Direction.java                                                                             |   19 
 .metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache                                              |    0 
 src/frame/object/data/OrderBy.java                                                                        |   24 
 src/frame/expression/IVariantRequestListener.java                                                         |   11 
 src/frame/persist/loader/EntityLoader.java                                                                |   41 
 src/frame/file/FileIOContext.java                                                                         |  229 
 src/frame/file/IFileContext.java                                                                          |   11 
 WebRoot/js/card.js                                                                                        |  339 
 WebRoot/js/extend.js                                                                                      |   54 
 src/frame/role/UserVariantProvider.java                                                                   |   81 
 src/frame/persist/SQLBuilder.java                                                                         |  104 
 src/frame/data/convert/ObjectTranslator.java                                                              |  193 
 .metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml                                       |    2 
 src/frame/persist/loader/ListLoader.java                                                                  |   56 
 src/frame/persist/NamedSQL.java                                                                           |  392 +
 src/frame/persist/IDoubleSavable.java                                                                     |   10 
 src/frame/data/DataPool.java                                                                              |  118 
 src/frame/data/convert/LongTranslator.java                                                                |   82 
 src/frame/object/data/IFilterSegmentProvider.java                                                         |    7 
 src/frame/file/office/Engine.java                                                                         |  125 
 src/frame/persist/IMetaDataLoader.java                                                                    |   11 
 WebRoot/css/home.css                                                                                      |   50 
 src/frame/expression/IVariantParseListener.java                                                           |    9 
 .metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml                                                 |    2 
 src/frame/file/CellTypes.java                                                                             |   71 
 .mymetadata                                                                                               |   13 
 WebRoot/js/grid.js                                                                                        |  893 ++
 src/frame/schedule/ScheduleJob.java                                                                       |  119 
 src/frame/object/http/ResultItem.java                                                                     |   39 
 .settings/org.eclipse.jdt.core.prefs                                                                      |    8 
 src/frame/object/data/Initializer.java                                                                    |   36 
 src/frame/object/http/Path.java                                                                           |  188 
 src/frame/call/writer/IEnvelop.java                                                                       |   34 
 .metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources                       |    0 
 src/frame/schedule/IJob.java                                                                              |   37 
 WebRoot/page/demo.html                                                                                    |   74 
 .metadata/.plugins/org.eclipse.dltk.core/Containers.dat                                                   |    0 
 src/frame/call/writer/JsonWriter.java                                                                     |  156 
 WebRoot/image/tree/tree-status-close.gif                                                                  |    0 
 src/frame/data/Variant.java                                                                               |  270 
 src/frame/persist/IStepSavable.java                                                                       |   12 
 WebRoot/css/dialog.css                                                                                    |  154 
 WebRoot/page/knowledge.html                                                                               |   23 
 src/frame/file/office/IOMappingItemRuntime.java                                                           |   81 
 src/frame/server/DataSourceLoader.java                                                                    |    5 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs                     |    3 
 WebRoot/css/tree.css                                                                                      |  194 
 src/frame/persist/ILoadable.java                                                                          |    9 
 .metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version                              |    1 
 src/frame/persist/NamedSQLLoader.java                                                                     |  125 
 src/frame/data/EntitySet.java                                                                             |  118 
 WebRoot/js/loading.js                                                                                     |   92 
 src/frame/persist/IStepLoadable.java                                                                      |   15 
 src/frame/expression/IExpression.java                                                                     |    8 
 src/frame/persist/SQLRunner.java                                                                          |  785 ++
 .metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat                                        |    0 
 src/frame/data/DataType.java                                                                              |  195 
 src/frame/data/DataContext.java                                                                           |   39 
 src/frame/schedule/Timer.java                                                                             |   24 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.examples.prefs                 |    3 
 WebRoot/image/tree/tree-noline.gif                                                                        |    0 
 WebRoot/js/dialog.js                                                                                      |  157 
 .settings/org.eclipse.wst.common.project.facet.core.xml                                                   |    7 
 .settings/org.eclipse.wst.jsdt.ui.superType.name                                                          |    1 
 src/frame/data/Page.java                                                                                  |  156 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs                          |   11 
 src/frame/object/data/InitializerContainer.java                                                           |   10 
 src/frame/file/processor/Phase.java                                                                       |   44 
 .metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml                                           |    3 
 src/frame/file/AppendMode.java                                                                            |   31 
 WebRoot/css/main.css                                                                                      |   38 
 src/frame/object/data/Id.java                                                                             |   26 
 src/frame/role/Scenario.java                                                                              |   42 
 src/frame/server/Dispatcher.java                                                                          |  333 
 .settings/org.eclipse.wst.common.component                                                                |    9 
 src/frame/expression/GlobalVariant.java                                                                   |  131 
 src/frame/file/office/IOMappingRuntime.java                                                               |   90 
 src/frame/schedule/ExecuteResult.java                                                                     |    7 
 src/frame/config/Loader.java                                                                              |   48 
 src/frame/data/DataBaseType.java                                                                          |   29 
 src/frame/data/Entity.java                                                                                |  332 
 src/frame/data/IDataConsumer.java                                                                         |   13 
 .metadata/.plugins/org.eclipse.jdt.launching/.install.xml                                                 |    4 
 src/frame/persist/Result.java                                                                             |   81 
 src/frame/object/data/FilterSegment.java                                                                  |    5 
 src/frame/data/PropertyIterator.java                                                                      |   35 
 src/frame/util/Util.java                                                                                  |  548 +
 .metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml                                           |    2 
 .metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml                                             |   21 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs                      |    5 
 src/frame/file/exception/FileInvalidException.java                                                        |    5 
 src/frame/schedule/Schedule.java                                                                          |  112 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse.client.targetcfg.collab.ui.prefs |    3 
 src/frame/file/office/IOHandler.java                                                                      |  110 
 src/frame/data/reader/IEntityReader.java                                                                  |    9 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs                            |    6 
 WebRoot/image/tree/tree-status.gif                                                                        |    0 
 WebRoot/js/tree.js                                                                                        |  475 +
 src/frame/object/http/RequestType.java                                                                    |    7 
 src/frame/call/writer/IBeanWriter.java                                                                    |   10 
 src/frame/data/reader/EntityReaderContainer.java                                                          |   73 
 src/frame/object/data/DataObject.java                                                                     |  210 
 src/frame/role/OnlineAnymous.java                                                                         |   26 
 src/frame/role/Role.java                                                                                  |   78 
 src/frame/persist/loader/ResultSetFieldReader.java                                                        |   47 
 .metadata/.plugins/org.eclipse.ui.workbench/workbench.xml                                                 |  297 
 src/frame/data/IDataProvider.java                                                                         |   13 
 src/frame/file/office/IOProcessor.java                                                                    |   41 
 src/frame/object/data/Filter.java                                                                         |   31 
 .project                                                                                                  |   58 
 src/frame/role/OnlineUser.java                                                                            |  270 
 src/frame/data/convert/DateTranslator.java                                                                |  108 
 WebRoot/css/card.css                                                                                      |   71 
 WebRoot/image/tree/tree-level.gif                                                                         |    0 
 src/frame/persist/loader/DataLoader.java                                                                  |   44 
 WebRoot/js/core.js                                                                                        |  446 +
 WebRoot/js/control.js                                                                                     | 2751 +++++++
 src/frame/data/meta/EntityMeta.java                                                                       |  416 +
 WebRoot/image/tree/tree-leaf.gif                                                                          |    0 
 WebRoot/page/file/fileio.html                                                                             |  114 
 src/frame/expression/VariantContext.java                                                                  |   70 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs                    |    3 
 src/frame/config/Configer.java                                                                            |  224 
 src/frame/persist/DataCenter.java                                                                         |   81 
 .metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache                                              |    0 
 src/frame/persist/loader/ResultMetaFieldReader.java                                                       |   50 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs                       |    3 
 src/frame/server/ContextListener.java                                                                     |   26 
 WebRoot/page/project.html                                                                                 |   23 
 .metadata/.plugins/org.eclipse.wst.common.snippets/user.xml                                               |    0 
 WebRoot/image/tree/tree.gif                                                                               |    0 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.core.prefs                     |    3 
 WebRoot/css/demo.css                                                                                      |   50 
 src/frame/persist/ISavable.java                                                                           |   10 
 src/frame/schedule/ITask.java                                                                             |    7 
 src/frame/expression/VariantRequestParams.java                                                            |   22 
 src/frame/persist/NamedDataSource.java                                                                    |   18 
 .settings/com.genuitec.eclipse.core.prefs                                                                 |    4 
 src/frame/file/exception/DataInvalidException.java                                                        |    5 
 src/frame/data/reader/ObjectPropertyRecorder.java                                                         |   95 
 WebRoot/page/demo_container/demo_home.html                                                                |   35 
 src/frame/config/ILoader.java                                                                             |   15 
 src/frame/data/meta/IFieldReader.java                                                                     |   20 
 WebRoot/css/grid.css                                                                                      |  272 
 src/frame/persist/loader/ObjectLoader.java                                                                |   58 
 src/frame/data/meta/IMetaDataLoader.java                                                                  |   11 
 src/frame/persist/NamedSQLContainer.java                                                                  |   71 
 .settings/.jsdtscope                                                                                      |   12 
 WebRoot/page/demo_container/demo_tab.html                                                                 |   23 
 src/frame/data/convert/StringTranslator.java                                                              |  174 
 src/frame/schedule/JobStatus.java                                                                         |    6 
 src/frame/role/Statistics.java                                                                            |   52 
 WebRoot/js/jquery-1.7.2.min.js                                                                            |    4 
 WebRoot/index.jsp                                                                                         |   26 
 .metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version                           |    1 
 WebRoot/WEB-INF/web.xml                                                                                   |   11 
 src/frame/role/OrgRight.java                                                                              |    5 
 .classpath                                                                                                |   19 
 src/frame/file/office/IOMappingItem.java                                                                  |   76 
 src/frame/role/User.java                                                                                  |  235 
 src/frame/object/http/JsonItem.java                                                                       |    5 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs                            |   14 
 src/frame/persist/loader/EntitySetLoader.java                                                             |   44 
 WebRoot/META-INF/MANIFEST.MF                                                                              |    3 
 WebRoot/page/api.html                                                                                     |   23 
 src/frame/expression/Segment.java                                                                         |   18 
 src/frame/data/meta/Field.java                                                                            |  410 +
 WebRoot/css/loading.css                                                                                   |   45 
 src/frame/data/convert/Convertor.java                                                                     |  132 
 src/frame/util/MapList.java                                                                               |  194 
 src/frame/persist/loader/PrimaryKeyLoader.java                                                            |   72 
 src/frame/file/processor/Processor.java                                                                   |  198 
 src/frame/object/http/ResultPool.java                                                                     |  150 
 src/frame/data/DataLink.java                                                                              |   80 
 .metadata/.lock                                                                                           |    0 
 src/frame/data/reader/ObjectReader.java                                                                   |  431 +
 src/frame/role/UserRightContainer.java                                                                    |   90 
 src/frame/expression/VariantList.java                                                                     |   12 
 src/frame/data/meta/MetaContainer.java                                                                    |   52 
 src/frame/util/ContentBuilder.java                                                                        |   83 
 src/frame/data/reader/MapReader.java                                                                      |  113 
 src/frame/file/processor/Monitor.java                                                                     |   16 
 src/frame/data/meta/MetaDataLoader.java                                                                   |   77 
 src/frame/call/writer/EnvelopWriter.java                                                                  |  535 +
 .metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml                                           |    5 
 src/frame/file/CellDataType.java                                                                          |    5 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.myeclipse.compatibility.prefs          |    4 
 .settings/org.eclipse.wst.jsdt.ui.superType.container                                                     |    1 
 src/frame/object/http/ObjectItem.java                                                                     |    5 
 WebRoot/image/tree/tree-status-open.gif                                                                   |    0 
 src/frame/role/DepartmentRight.java                                                                       |    5 
 src/frame/util/MapTree.java                                                                               |  105 
 .metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml                                               |    4 
 src/frame/persist/SQLVariant.java                                                                         |   26 
 src/frame/file/office/IOMapping.java                                                                      |  226 
 .metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml                                        |  356 
 src/frame/data/convert/DoubleTranslator.java                                                              |  129 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs                           |    3 
 .metadata/.plugins/org.eclipse.core.resources/.root/1.tree                                                |    0 
 src/frame/file/FileIO.java                                                                                |   76 
 src/frame/server/ServerInstance.java                                                                      |  133 
 src/frame/role/UserRight.java                                                                             |   19 
 .metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml                                        |    2 
 WebRoot/page/home.html                                                                                    |   42 
 src/frame/data/convert/IntegerTranslator.java                                                             |  120 
 src/frame/expression/VariantNotFoundException.java                                                        |   10 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse2.common.ui.prefs                 |    3 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.wizards.prefs                  |   19 
 src/frame/data/convert/BooleanTranslator.java                                                             |  112 
 .metadata/.plugins/com.genuitec.eclipse.sqlexplorer/ConnectionProfiles.xml                                |   18 
 src/frame/data/DataCell.java                                                                              |   21 
 src/frame/file/FileIOItem.java                                                                            |  220 
 src/frame/expression/StringSegment.java                                                                   |   26 
 src/frame/file/IFileload.java                                                                             |    9 
 .metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.0.0.20110607-2117.xml                  |   41 
 src/frame/file/FileIOContainer.java                                                                       |  230 
 .metadata/version.ini                                                                                     |    1 
 src/frame/data/reader/PropertyReader.java                                                                 |   36 
 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs                     |    3 
 .metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index                             |    0 
 src/frame/config/ContextConfigerLoader.java                                                               |  311 
 src/frame/file/DeleteMode.java                                                                            |   31 
 src/frame/expression/VariantSegment.java                                                                  |   52 
 WebRoot/page/main.html                                                                                    |   44 
 src/frame/config/LoaderContainer.java                                                                     |   33 
 .metadata/.plugins/org.eclipse.wst.common.snippets/hidden.xml                                             |    0 
 src/frame/expression/VariantParser.java                                                                   |  107 
 src/frame/persist/ConnectionManager.java                                                                  |   79 
 WebRoot/page/file/filerecord.html                                                                         |  194 
 WebRoot/page/file/upload.html                                                                             |  238 
 src/frame/object/http/HttpObject.java                                                                     |  233 
 WebRoot/page/file/filelog.html                                                                            |  192 
 245 files changed, 23,349 insertions(+), 0 deletions(-)

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..c5aa531
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7"/>
+	<classpathentry kind="con" path="melibrary.com.genuitec.eclipse.j2eedt.core.MYECLIPSE_JAVAEE_6_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
+	<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
+	<classpathentry kind="lib" path="WebRoot/lib/dom4j-1.6.1.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/druid-0.2.18.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/log4j-1.2.16.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/commons-codec-1.10.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/commons-collections4-4.1.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/commons-logging-1.2.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/junit-4.12.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/poi-3.17.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/poi-ooxml-3.17.jar"/>
+	<classpathentry kind="lib" path="WebRoot/lib/poi-ooxml-schemas-3.17.jar"/>
+	<classpathentry kind="output" path="WebRoot/WEB-INF/classes"/>
+</classpath>
diff --git a/.metadata/.lock b/.metadata/.lock
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.metadata/.lock
diff --git a/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/ConnectionProfiles.xml b/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/ConnectionProfiles.xml
new file mode 100644
index 0000000..ebfab19
--- /dev/null
+++ b/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/ConnectionProfiles.xml
@@ -0,0 +1,18 @@
+<Beans>
+    <Bean Class="com.genuitec.eclipse.sqlexplorer.utils.ConnectionProfile">
+        <activate>false</activate>
+        <driverIdentifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-fd14b7f:163ba37a907:-7fde</string>
+        </driverIdentifier>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-fd14b7f:163ba37a907:-7fdd</string>
+        </identifier>
+        <name>MyEclipse Derby</name>
+        <password encryption="true">gFOjO/OmrJ8m4/rtM2cMIw==</password>
+        <promptForPassword>false</promptForPassword>
+        <schema Indexed="true"/>
+        <schemaDisplayPolicy>0</schemaDisplayPolicy>
+        <url>jdbc:derby://localhost:1527/myeclipse</url>
+        <userName>classiccars</userName>
+    </Bean>
+</Beans>
diff --git a/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml b/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml
new file mode 100644
index 0000000..cdb6353
--- /dev/null
+++ b/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml
@@ -0,0 +1,356 @@
+<Beans>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.pointbase.net.netJDBCDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-23</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Pointbase Embedded</name>
+        <url>jdbc:pointbase:embedded:&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>COM.ibm.db2.jdbc.net.DB2Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-24</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>IBM DB2 (App driver)</name>
+        <url>jdbc:db2://&lt;host_name&gt;:6789/&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.sap.dbtech.jdbc.DriverSapDB</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-21</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>SAPDB</name>
+        <url>jdbc:sapdb:[//host/]dbname[?name=value[&amp;name=value]*]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.pointbase.net.netJDBCDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-22</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Pointbase Server</name>
+        <url>jdbc:pointbase:server://&lt;server_name&gt;/&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.hsqldb.jdbcDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-20</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>HSQLDB In-Memory</name>
+        <url>jdbc:hsqldb:.</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.apache.derby.jdbc.ClientDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-29</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Derby</name>
+        <url>jdbc:derby://&lt;server_name&gt;:&lt;port&gt;/&lt;databaseName&gt;[;create=true]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.microsoft.sqlserver.jdbc.SQLServerDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-28</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Microsoft SQL Server 2005</name>
+        <url>jdbc:sqlserver://&lt;server_name&gt;:&lt;port&gt;[;databaseName=&lt;dbname&gt;]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.ncr.teradata.TeraDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-27</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Teradata</name>
+        <url>jdbc:teradata:[//host[:1025]/]&lt;database&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.mysql.jdbc.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-26</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>MySQL Connector/J</name>
+        <url>jdbc:mysql://&lt;hostname&gt;[&lt;:3306&gt;]/&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.firebirdsql.jdbc.FBDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-25</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Firebird (JayBird JCA/JDBC driver)</name>
+        <url>jdbc:firebirdsql:[//host[:port]/]&lt;database&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.sunopsis.jdbc.driver.xml.SnpsXmlDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-10</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Sunopsis XML</name>
+        <url>jdbc:snps:xml?f=&lt;file-name&gt;&amp;ro=true</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.microsoft.jdbc.sqlserver.SQLServerDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-11</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Microsoft SQL Server</name>
+        <url>jdbc:microsoft:sqlserver://&lt;server_name&gt;:&lt;1433&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.ibm.db2.jcc.DB2Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-30</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Derby (IBM Universal driver)</name>
+        <url>jdbc:db2://&lt;server_name&gt;:&lt;port&gt;/&lt;databaseName&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.mimer.jdbc.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-12</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Mimer SQL</name>
+        <url>jdbc:mimer:[//[&lt;user&gt;[:&lt;password&gt;]@]&lt;server&gt;[:&lt;1360&gt;]][/&lt;dbname&gt;][property-list]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.ibm.db2.jdbc.net.DB2Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-31</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>IBM DB2 (Universal driver)</name>
+        <url>jdbc:db2://&lt;host_name&gt;:&lt;port&gt;/&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.axiondb.jdbc.AxionDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-13</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Axion</name>
+        <url>jdbc:axiondb:&lt;database-name&gt;[:&lt;database-directory&gt;]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.ibm.db2.jdbc.net.DB2Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-32</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>IBM DB2 (Universal Type 2 driver)</name>
+        <url>jdbc:db2:&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>net.sourceforge.jtds.jdbc.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-33</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Microsoft SQL Server (jTDS driver)</name>
+        <url>jdbc:jtds:sqlserver://&lt;hostname&gt;[:&lt;port&gt;]/&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>net.sourceforge.jtds.jdbc.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-34</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Sybase (jTDS driver)</name>
+        <url>jdbc:jtds:sybase://&lt;hostname&gt;[:&lt;port&gt;]/&lt;dbname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.sqlite.JDBC</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-35</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>SQLite</name>
+        <url>jdbc:sqlite:&lt;path-to-db-file&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.hsqldb.jdbcDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-19</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>HSQLDB Standalone</name>
+        <url>jdbc:hsqldb:&lt;databaseName&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.hsqldb.jdbcDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-18</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>HSQLDB Server</name>
+        <url>jdbc:hsqldb:hsql://&lt;server&gt;[:&lt;1476&gt;]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.apache.derby.jdbc.ClientDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-fd14b7f:163ba37a907:-7fde</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true">
+            <Bean Class="net.sourceforge.squirrel_sql.fw.util.beanwrapper.StringWrapper">
+                <string>C:\Users\He.He\.myeclipse\libs\derby_10.2.2.0\derbyclient.jar</string>
+            </Bean>
+        </jarFileNames>
+        <name>MyEclipse Derby</name>
+        <url>jdbc:derby://&lt;host&gt;:&lt;port&gt;/&lt;db&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.mckoi.JDBCDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-15</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Mckoi</name>
+        <url>jdbc:mckoi://&lt;host&gt;[:9157][/&lt;schema&gt;]/</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-2</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Oracle (OCI driver)</name>
+        <url>jdbc:oracle:oci8:@&lt;database_name&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>sun.jdbc.odbc.JdbcOdbcDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-1</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>JDBC ODBC Bridge</name>
+        <url>jdbc:odbc:&lt;alias&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>uk.co.thinksql.ThinkSQLDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-14</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>ThinkSQL</name>
+        <url>jdbc:thinksql://&lt;server&gt;:&lt;9075&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.hsqldb.jdbcDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-17</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>HSQLDB Web Server</name>
+        <url>jdbc:hsqldb:http://&lt;server&gt;[:&lt;1476&gt;]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-4</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Oracle (Thin driver)</name>
+        <url>jdbc:oracle:thin:@&lt;server&gt;[:&lt;1521&gt;]:&lt;database_name&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.internetcds.jdbc.tds.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-16</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>jTDS (FreeTDS)</name>
+        <url>jdbc:freetds:sqlserver://&lt;hostname&gt;[:&lt;4100&gt;]/&lt;dbname&gt;[;&lt;property&gt;=&lt;value&gt;[;...]]</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>interbase.interclient.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-3</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>InterClient</name>
+        <url>jdbc:interbase://&lt;server&gt;/&lt;full_db_path&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.enhydra.instantdb.jdbc.idbDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-5</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>InstantDB</name>
+        <url>jdbc:idb:&lt;pathname&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.sybase.jdbc2.jdbc.SybDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-8</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Sybase Adaptive Server Anywhere</name>
+        <url>jdbc:sybase:Tds:&lt;host&gt;:&lt;port&gt;?ServiceName=&lt;DBNAME&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>org.postgresql.Driver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-7</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>PostgreSQL</name>
+        <url>jdbc:postgresql:[&lt;//host&gt;[:&lt;5432&gt;/]]&lt;database&gt;</url>
+    </Bean>
+    <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver">
+        <driverClassName>com.sybase.jdbc2.jdbc.SybDriver</driverClassName>
+        <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier">
+            <string>-9</string>
+        </identifier>
+        <jarFileName/>
+        <jarFileNames Indexed="true"/>
+        <name>Sybase Adaptive Server Enterprise</name>
+        <url>jdbc:sybase:Tds:&lt;host&gt;:&lt;port&gt;/&lt;DBNAME&gt;</url>
+    </Bean>
+</Beans>
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
new file mode 100644
index 0000000..25cb955
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
new file mode 100644
index 0000000..8aa4d6a
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
new file mode 100644
index 0000000..6b2aaa7
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
new file mode 100644
index 0000000..e20ad78
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
new file mode 100644
index 0000000..f80ede3
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.derby.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.derby.prefs
new file mode 100644
index 0000000..f88dd9f
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.derby.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:21:56 CST 2018
+eclipse.preferences.version=1
+DRIVER_CREATED=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.examples.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.examples.prefs
new file mode 100644
index 0000000..8d04196
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.examples.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:21:56 CST 2018
+eclipse.preferences.version=1
+repository_added=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.wizards.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.wizards.prefs
new file mode 100644
index 0000000..b4b1832
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.wizards.prefs
@@ -0,0 +1,19 @@
+#Fri Jun 01 15:21:56 CST 2018
+applet.template.2.label=Template for Applet with JDK1.4
+applet.template.1.label=Template for Applet with JDK1.3
+snippetLibIntalled_v5=true
+eclipse.preferences.version=1
+applethtml.template.1.label=Default Applet HTML template
+servlet.template.1=templates/Servlet.java
+applethtml.template.1=templates/Applet.html
+applet.template.2=templates/Applet14.java
+applet.template.1=templates/Applet.java
+servlet.template.1.label=Default template for Servlet
+doctype.html.8=<\!DOCTYPE HTML PUBLIC "-//IETF//DTD LEVEL1//EN">
+doctype.html.7=<\!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+doctype.html.6=<\!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
+doctype.html.5=<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+doctype.html.4=<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+doctype.html.3=<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+doctype.html.2=<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+doctype.html.1=<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.myeclipse.compatibility.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.myeclipse.compatibility.prefs
new file mode 100644
index 0000000..d599ad0
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.myeclipse.compatibility.prefs
@@ -0,0 +1,4 @@
+#Fri Jun 01 15:21:56 CST 2018
+eclipse.preferences.version=1
+preferencesMigrated=true
+preferencesMigrated60=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse.client.targetcfg.collab.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse.client.targetcfg.collab.ui.prefs
new file mode 100644
index 0000000..e9bdf6e
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse.client.targetcfg.collab.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:20:03 CST 2018
+eclipse.preferences.version=1
+com.genuitec.pulse.targetcfg.notify.dashboard.subsequent.launch=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse2.common.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse2.common.ui.prefs
new file mode 100644
index 0000000..77c8626
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.pulse2.common.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:20:00 CST 2018
+eclipse.preferences.version=1
+com.genuitec.pulse.client.targetcfg.synced.proxy.settings=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..5654222
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:20:05 CST 2018
+version=1
+eclipse.preferences.version=1
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d691f31
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+#Fri Jun 01 15:20:05 CST 2018
+org.eclipse.jdt.core.classpathVariable.JRE_SRCROOT=
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.classpathVariable.JRE_LIB=D\:/myeclipse/Common/binary/com.sun.java.jdk.win32.x86_64_1.6.0.013/jre/lib/rt.jar
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.classpathVariable.JRE_SRC=D\:/myeclipse/Common/binary/com.sun.java.jdk.win32.x86_64_1.6.0.013/src.zip
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..3030bc7
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:20:04 CST 2018
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_VM_XML=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<vmSettings defaultVM\="57,org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType45,pulse_com.sun.java.jdk.win32.x86_64_1.6.0.013">\r\n<vmType id\="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType">\r\n<vm id\="pulse_com.sun.java.jdk.win32.x86_64_1.6.0.013" name\="Sun JDK 1.6.0_13" path\="D\:\\myeclipse\\Common\\binary\\com.sun.java.jdk.win32.x86_64_1.6.0.013"/>\r\n</vmType>\r\n</vmSettings>\r\n
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..cc613c9
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,14 @@
+#Fri Jun 01 15:21:56 CST 2018
+useQuickDiffPrefPage=true
+proposalOrderMigrated=true
+tabWidthPropagated=true
+content_assist_proposals_background=255,255,255
+org.eclipse.jdt.ui.javadoclocations.migrated=true
+useAnnotationsPrefPage=true
+org.eclipse.jface.textfont=1|Consolas|10.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas;
+org.eclipse.jdt.ui.editor.tab.width=
+org.eclipse.jdt.ui.formatterprofiles.version=12
+spelling_locale_initialized=true
+eclipse.preferences.version=1
+content_assist_proposals_foreground=0,0,0
+fontPropagated=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
new file mode 100644
index 0000000..5ea836c
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:21:56 CST 2018
+eclipse.preferences.version=1
+org.eclipse.m2e.discovery.pref.projects=
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.core.prefs
new file mode 100644
index 0000000..30f1e85
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.core.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:20:00 CST 2018
+repositories/%pserver%anonymous@examples.myeclipseide.com%%home%cvs%public%myeclipse%examples/location=\:pserver\:anonymous@examples.myeclipseide.com\:/home/cvs/public/myeclipse/examples
+eclipse.preferences.version=1
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs
new file mode 100644
index 0000000..da723dd
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:21:56 CST 2018
+pref_first_startup=false
+eclipse.preferences.version=1
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs
new file mode 100644
index 0000000..7dc3796
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Jun 01 15:21:56 CST 2018
+eclipse.preferences.version=1
+org.eclipse.team.ui.first_time=false
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
new file mode 100644
index 0000000..a8c498a
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 01 15:21:57 CST 2018
+eclipse.preferences.version=1
+tipsAndTricks=false
+platformState=1505098145356
+quickStart=false
+PROBLEMS_FILTERS_MIGRATE=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
new file mode 100644
index 0000000..b563d07
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
@@ -0,0 +1,5 @@
+#Fri Jun 01 15:21:56 CST 2018
+PLUGINS_NOT_ACTIVATED_ON_STARTUP=org.eclipse.m2e.discovery;
+eclipse.preferences.version=1
+//org.eclipse.ui.commands/state/org.eclipse.wst.xml.views.XPathView.processor.xpathprocessor/org.eclipse.ui.commands.radioState=xpath10
+ENABLED_DECORATORS=org.eclipse.jst.j2ee.navigator.ui.java.resource.decorator\:true,org.eclipse.m2e.core.mavenVersionDecorator\:false,org.eclipse.wst.server.ui.decorator\:false,com.aptana.ide.syncing.SyncConnectionDecorator\:true,com.aptana.ide.syncing.VirtualFileCloakedDecorator\:true,com.aptana.ide.syncing.VirtualFileManagerSyncDecorator\:true,com.aptana.ide.syncing.SyncProjectConnectionDecorator\:true,com.aptana.ide.syncing.VirtualProjectCloakedDecorator\:true,com.genuitec.myeclipse.ui.decoration.myEclipseUniversalDecorator\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.DependencyDecoration\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.ColumnDecoration\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.ForeignKeyDecoration\:true,org.eclipse.datatools.connectivity.sqm.core.internal.ui.explorer.IndexTriggerDecoration\:true,org.eclipse.datatools.connectivity.internal.core.ui.bookmarkDecoration\:true,org.eclipse.datatools.connectivity.internal.core.ui.FilterNodeDecoration\:true,org.eclipse.datatools.connectivity.ui.decorator.contentextension\:false,org.eclipse.datatools.enablement.ingres.ui.providers.decorators.SynonymDecorationService\:true,org.eclipse.datatools.enablement.ingres.internal.ui.providers.decorators.ParameterDecorationService\:true,org.eclipse.datatools.enablement.sybase.asa.proxytabledecorator\:true,org.eclipse.datatools.enablement.sybase.ase.webservicetabledecorator\:true,org.eclipse.datatools.enablement.sybase.systemtabledecorator\:true,org.eclipse.jdt.ui.override.decorator\:true,org.eclipse.jdt.ui.interface.decorator\:false,org.eclipse.jdt.ui.buildpath.decorator\:true,org.eclipse.jst.j2ee.internal.ui.util.AnnotationIconDecorator_ejb\:true,org.eclipse.jst.jee.ui.internal.navigator.ejb.BeanDecorator\:true,org.eclipse.jst.jee.navigator.internal.JEEProjectDecorator\:true,org.eclipse.jst.j2ee.internal.ui.util.AnnotationIconDecorator_servlet\:true,org.eclipse.jst.servlet.ui.Decorator\:true,org.eclipse.m2e.core.maven2decorator\:true,org.eclipse.pde.ui.binaryProjectDecorator\:false,org.eclipse.team.cvs.ui.decorator\:true,org.eclipse.ui.LinkedResourceDecorator\:true,org.eclipse.ui.VirtualResourceDecorator\:true,org.eclipse.ui.ContentTypeDecorator\:true,org.eclipse.ui.ResourceFilterDecorator\:false,org.eclipse.wst.jsdt.ui.override.decorator\:true,org.eclipse.wst.server.ui.navigatorDecorator\:true,org.springframework.ide.eclipse.aop.ui.decorator.advicedecorator\:true,org.springframework.ide.eclipse.beans.ui.model.beansModelLabelDecorator\:true,org.springframework.ide.eclipse.ui.model.modelLabelDecorator\:true,org.springframework.ide.eclipse.webflow.ui.model.webflowModelLabelDecorator\:true,org.tigris.subversion.subclipse.ui.decorator\:true,org.topcased.validation.ui.views.EMFMarkerDecorator\:true,
diff --git a/.metadata/.plugins/org.eclipse.dltk.core/Containers.dat b/.metadata/.plugins/org.eclipse.dltk.core/Containers.dat
new file mode 100644
index 0000000..9c82273
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.dltk.core/Containers.dat
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache
new file mode 100644
index 0000000..593f470
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
new file mode 100644
index 0000000..593f470
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
new file mode 100644
index 0000000..9fee426
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml
new file mode 100644
index 0000000..db24f21
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<dirs>
+<entry loc="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013" stamp="1505097950252"/>
+</dirs>
diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml b/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml
new file mode 100644
index 0000000..dfc18c9
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<libraryInfos>
+<libraryInfo home="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013" version="1.6.0_13">
+<bootpath>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\resources.jar"/>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\rt.jar"/>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\sunrsasign.jar"/>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\jsse.jar"/>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\jce.jar"/>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\charsets.jar"/>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\classes"/>
+</bootpath>
+<extensionDirs>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\ext"/>
+<entry path="C:\Windows\Sun\Java\lib\ext"/>
+</extensionDirs>
+<endorsedDirs>
+<entry path="D:\myeclipse\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\endorsed"/>
+</endorsedDirs>
+</libraryInfo>
+</libraryInfos>
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
new file mode 100644
index 0000000..a4ee3cb
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<typeInfoHistroy/>
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
new file mode 100644
index 0000000..9e390f5
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<qualifiedTypeNameHistroy/>
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
new file mode 100644
index 0000000..3304146
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section name="Workbench">
+	<section name="org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart">
+		<item value="true" key="group_libraries"/>
+		<item value="false" key="linkWithEditor"/>
+		<item value="2" key="layout"/>
+		<item value="1" key="rootMode"/>
+		<item value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#x0D;&#x0A;&lt;packageExplorer group_libraries=&quot;1&quot; layout=&quot;2&quot; linkWithEditor=&quot;0&quot; rootMode=&quot;1&quot; workingSetName=&quot;&quot;&gt;&#x0D;&#x0A;&lt;customFilters userDefinedPatternsEnabled=&quot;false&quot;&gt;&#x0D;&#x0A;&lt;xmlDefinedFilters&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.LibraryFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.LocalTypesFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.StaticsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.pde.ui.ExternalPluginLibrariesFilter1&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.ClosedProjectsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonSharedProjectsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonJavaElementFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.ContainedLibraryFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.CuAndClassFileFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonJavaProjectsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.internal.ui.PackageExplorer.EmptyInnerPackageFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.PackageDeclarationFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.internal.ui.PackageExplorer.EmptyPackageFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.ImportDeclarationFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.FieldsFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.internal.ui.PackageExplorer.HideInnerClassFilesFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.NonPublicFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer_patternFilterId_.*&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.EmptyLibraryContainerFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.pde.ui.BinaryProjectFilter1&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.jdt.ui.PackageExplorer.SyntheticMembersFilter&quot; isEnabled=&quot;true&quot;/&gt;&#x0D;&#x0A;&lt;child filterId=&quot;org.eclipse.m2e.MavenModuleFilter&quot; isEnabled=&quot;false&quot;/&gt;&#x0D;&#x0A;&lt;/xmlDefinedFilters&gt;&#x0D;&#x0A;&lt;/customFilters&gt;&#x0D;&#x0A;&lt;/packageExplorer&gt;" key="memento"/>
+	</section>
+</section>
diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.0.0.20110607-2117.xml b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.0.0.20110607-2117.xml
new file mode 100644
index 0000000..e0de515
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.0.0.20110607-2117.xml
@@ -0,0 +1,41 @@
+<configuration scan="true">
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+      <pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
+    </encoder>
+    <filter class="org.eclipse.m2e.logback.appender.ConsoleAppenderFilter"/>
+  </appender>
+
+  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <File>${org.eclipse.m2e.log.dir}/0.log</File>
+    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <FileNamePattern>${org.eclipse.m2e.log.dir}/%i.log</FileNamePattern>
+      <MinIndex>1</MinIndex>
+      <MaxIndex>10</MaxIndex>
+    </rollingPolicy>
+    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <MaxFileSize>100MB</MaxFileSize>
+    </triggeringPolicy>
+    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+      <pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <appender name="EclipseLog" class="org.eclipse.m2e.logback.appender.EclipseLogAppender">
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+      <level>WARN</level>
+    </filter>
+  </appender>
+
+  <appender name="MavenConsoleLog" class="org.eclipse.m2e.logback.appender.MavenConsoleAppender">
+  </appender>
+        
+  <root level="INFO">
+    <appender-ref ref="FILE" />
+    <appender-ref ref="STDOUT" />
+    <appender-ref ref="EclipseLog" />
+    <appender-ref ref="MavenConsoleLog" />
+  </root>
+
+  <logger name="com.ning.http.client" level="INFO" />
+</configuration>
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml
new file mode 100644
index 0000000..193673b
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CommitCommentTemplates></CommitCommentTemplates>
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml
new file mode 100644
index 0000000..891f130
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CommitComments></CommitComments>
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml
new file mode 100644
index 0000000..8bda64f
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repositories-view>
+	<repository id=":pserver:anonymous@examples.myeclipseide.com:/home/cvs/public/myeclipse/examples" name="MyEclipse Examples">
+	</repository>
+</repositories-view>
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml
new file mode 100644
index 0000000..5ca0b77
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section name="Workbench">
+</section>
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml
new file mode 100644
index 0000000..530964c
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<workbench progressCount="16" version="2.0">
+<workbenchAdvisor/>
+<window height="768" width="1024" x="75" y="75">
+<fastViewData fastViewLocation="1024"/>
+<perspectiveBar>
+<itemSize x="160"/>
+</perspectiveBar>
+<coolbarLayout>
+<coolItem id="group.file" itemType="typeGroupMarker"/>
+<coolItem id="org.eclipse.ui.workbench.file" itemType="typeToolBarContribution" x="262" y="22"/>
+<coolItem id="additions" itemType="typeGroupMarker"/>
+<coolItem id="com.genuitec.eclipse.j2eedt.core.ejb" itemType="typeToolBarContribution" x="55" y="22"/>
+<coolItem id="com.genuitec.eclipse.uml.actions" itemType="typeToolBarContribution" x="61" y="22"/>
+<coolItem id="com.genuitec.eclipse.web20.actionset" itemType="typeToolBarContribution" x="38" y="22"/>
+<coolItem id="com.genuitec.eclipse.ws.xfire.actions" itemType="typeToolBarContribution" x="95" y="22"/>
+<coolItem id="com.genuitec.myeclipse.actions.deploytools" itemType="typeToolBarContribution" x="101" y="22"/>
+<coolItem id="com.genuitec.myeclipse.actions.desktop" itemType="typeToolBarContribution" x="61" y="22"/>
+<coolItem id="com.genuitec.myeclipse.actions.reporting" itemType="typeToolBarContribution" x="78" y="22"/>
+<coolItem id="com.genuitec.myeclipse.actions.screencapture" itemType="typeToolBarContribution" x="55" y="22"/>
+<coolItem id="org.eclipse.debug.ui.launchActionSet" itemType="typeToolBarContribution" x="175" y="22"/>
+<coolItem id="org.eclipse.jdt.ui.JavaElementCreationActionSet" itemType="typeToolBarContribution" x="78" y="22"/>
+<coolItem id="org.eclipse.search.searchActionSet" itemType="typeToolBarContribution" x="101" y="22"/>
+<coolItem id="org.eclipse.wst.xml.ui.perspective.NewFileToolBar" itemType="typeToolBarContribution" x="-1" y="-1"/>
+<coolItem id="org.eclipse.wst.xml.ui.design.DesignToolBar" itemType="typeToolBarContribution" x="-1" y="-1"/>
+<coolItem id="group.nav" itemType="typeGroupMarker"/>
+<coolItem id="org.eclipse.ui.workbench.navigate" itemType="typeToolBarContribution" x="198" y="22"/>
+<coolItem id="group.editor" itemType="typeGroupMarker"/>
+<coolItem id="group.help" itemType="typeGroupMarker"/>
+<coolItem id="org.eclipse.ui.workbench.help" itemType="typeToolBarContribution" x="-1" y="-1"/>
+</coolbarLayout>
+<page aggregateWorkingSetId="Aggregate for window 1527837599746" focus="true" label="Workspace - MyEclipse Java Enterprise">
+<editors>
+<editorArea activeWorkbook="DefaultEditorWorkbook">
+<info part="DefaultEditorWorkbook">
+<folder appearance="1" expanded="2">
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory"/>
+</folder>
+</info>
+</editorArea>
+</editors>
+<views>
+<view id="com.genuitec.eclipse.ui.HTMLView" partName="Web Browser"/>
+<view id="org.eclipse.wst.common.snippets.internal.ui.SnippetsView" partName="Snippets"/>
+<view id="com.genuitec.eclipse.ast.deploy.core.serverview" partName="Servers"/>
+<view id="uky.article.imageviewer.views.ImageView" partName="Image Preview">
+<viewState/>
+</view>
+<view id="org.eclipse.jdt.ui.TypeHierarchy" partName="Type Hierarchy"/>
+<view id="org.eclipse.ui.views.PropertySheet" partName="Properties">
+<viewState/>
+</view>
+<view id="org.eclipse.ui.views.ProblemView" partName="Problems">
+<viewState PRIMARY_SORT_FIELD="org.eclipse.ui.ide.severityAndDescriptionField" categoryGroup="org.eclipse.ui.ide.severity" markerContentGenerator="org.eclipse.ui.ide.problemsGenerator" partName="Problems">
+<columnWidths org.eclipse.ui.ide.locationField="90" org.eclipse.ui.ide.markerType="90" org.eclipse.ui.ide.pathField="120" org.eclipse.ui.ide.resourceField="90" org.eclipse.ui.ide.severityAndDescriptionField="300"/>
+<visible IMemento.internal.id="org.eclipse.ui.ide.severityAndDescriptionField"/>
+<visible IMemento.internal.id="org.eclipse.ui.ide.resourceField"/>
+<visible IMemento.internal.id="org.eclipse.ui.ide.pathField"/>
+<visible IMemento.internal.id="org.eclipse.ui.ide.locationField"/>
+<visible IMemento.internal.id="org.eclipse.ui.ide.markerType"/>
+</viewState>
+</view>
+<view id="org.eclipse.ui.console.ConsoleView" partName="Console"/>
+<view id="org.eclipse.jdt.ui.PackageExplorer" partName="Package Explorer">
+<viewState group_libraries="1" layout="2" linkWithEditor="0" rootMode="1" workingSetName="">
+<customFilters userDefinedPatternsEnabled="false">
+<xmlDefinedFilters>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.LibraryFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.LocalTypesFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.StaticsFilter" isEnabled="false"/>
+<child filterId="org.eclipse.pde.ui.ExternalPluginLibrariesFilter1" isEnabled="true"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.ClosedProjectsFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonSharedProjectsFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonJavaElementFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.ContainedLibraryFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.CuAndClassFileFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonJavaProjectsFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.internal.ui.PackageExplorer.EmptyInnerPackageFilter" isEnabled="true"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.PackageDeclarationFilter" isEnabled="true"/>
+<child filterId="org.eclipse.jdt.internal.ui.PackageExplorer.EmptyPackageFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.ImportDeclarationFilter" isEnabled="true"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.FieldsFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.internal.ui.PackageExplorer.HideInnerClassFilesFilter" isEnabled="true"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonPublicFilter" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer_patternFilterId_.*" isEnabled="true"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.EmptyLibraryContainerFilter" isEnabled="true"/>
+<child filterId="org.eclipse.pde.ui.BinaryProjectFilter1" isEnabled="false"/>
+<child filterId="org.eclipse.jdt.ui.PackageExplorer.SyntheticMembersFilter" isEnabled="true"/>
+<child filterId="org.eclipse.m2e.MavenModuleFilter" isEnabled="false"/>
+</xmlDefinedFilters>
+</customFilters>
+</viewState>
+</view>
+<view id="org.eclipse.ui.views.TaskList" partName="Tasks"/>
+<view id="org.eclipse.ui.views.ContentOutline" partName="Outline">
+<viewState/>
+</view>
+</views>
+<perspectives activePart="org.eclipse.jdt.ui.PackageExplorer" activePerspective="com.genuitec.myeclipse.perspective.myeclipseperspective">
+<perspective editorAreaTrimState="2" editorAreaVisible="1" fixed="0" version="0.016">
+<descriptor class="com.genuitec.myeclipse.perspective.MyEclipsePerspectiveFactory" id="com.genuitec.myeclipse.perspective.myeclipseperspective" label="MyEclipse Java Enterprise"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.deploytools"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.test.actions"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.desktop"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.screencapture"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.examples.actionSet"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.hibernatetools"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.webtools"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.j2eedt.core.ejb"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.jsftools"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.faceletstools"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.maven.pro.actions"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.jpatools"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.portlet.portletactions"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.reporting"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.springtools"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.strutstools"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.actions.restsupport"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.ws.xfire.actions"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.icefaces"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.about.actions"/>
+<alwaysOnActionSet id="com.genuitec.myeclipse.product.actions"/>
+<alwaysOnActionSet id="org.eclipse.ui.cheatsheets.actionSet"/>
+<alwaysOnActionSet id="org.eclipse.search.searchActionSet"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.annotationNavigation"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.navigation"/>
+<alwaysOnActionSet id="org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo"/>
+<alwaysOnActionSet id="org.eclipse.ui.externaltools.ExternalToolsSet"/>
+<alwaysOnActionSet id="org.eclipse.ui.actionSet.keyBindings"/>
+<alwaysOnActionSet id="org.eclipse.ui.actionSet.openFiles"/>
+<alwaysOnActionSet id="org.springframework.ide.eclipse.aop.ui.ActionSet"/>
+<alwaysOnActionSet id="org.springframework.ide.eclipse.aop.ui.matcher.actionSet"/>
+<alwaysOnActionSet id="org.springframework.ide.eclipse.beans.ui.actionSet"/>
+<alwaysOnActionSet id="org.springframework.ide.eclipse.beans.search.actionSet"/>
+<alwaysOnActionSet id="org.eclipse.debug.ui.launchActionSet"/>
+<alwaysOnActionSet id="org.eclipse.jdt.ui.JavaActionSet"/>
+<alwaysOnActionSet id="org.eclipse.jdt.ui.JavaElementCreationActionSet"/>
+<alwaysOnActionSet id="org.eclipse.ui.NavigateActionSet"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.uml.actions"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.uml2.ui.actions"/>
+<alwaysOnActionSet id="org.eclipse.debug.ui.profileActionSet"/>
+<alwaysOnActionSet id="com.genuitec.eclipse.web20.actionset"/>
+<show_view_action id="com.genuitec.eclipse.ast.deploy.core.serverview"/>
+<show_view_action id="org.eclipse.jdt.ui.PackageExplorer"/>
+<show_view_action id="org.eclipse.jdt.ui.TypeHierarchy"/>
+<show_view_action id="org.eclipse.ui.console.ConsoleView"/>
+<show_view_action id="org.eclipse.ui.views.ContentOutline"/>
+<show_view_action id="org.eclipse.ui.views.TaskList"/>
+<show_view_action id="uky.article.imageviewer.views.ImageView"/>
+<show_view_action id="org.eclipse.wst.common.snippets.internal.ui.SnippetsView"/>
+<show_view_action id="org.eclipse.ui.views.PropertySheet"/>
+<show_view_action id="org.eclipse.ui.views.ProblemView"/>
+<show_view_action id="com.genuitec.eclipse.ui.HTMLView"/>
+<new_wizard_action id="com.genuitec.eclipse.j2eedt.ui.wizard.EJBProjectCreationWizard"/>
+<new_wizard_action id="com.genuitec.eclipse.j2eedt.ui.wizard.NewEARProjectWizard"/>
+<new_wizard_action id="com.genuitec.eclipse.j2eedt.ui.wizard.WebProjectCreationWizard"/>
+<new_wizard_action id="com.genuitec.eclipse.ws.xfire.wizards.NewXFireWebProjectWizard1"/>
+<new_wizard_action id="org.eclipse.jdt.ui.wizards.JavaProjectWizard"/>
+<new_wizard_action id="org.eclipse.jdt.ui.wizards.NewPackageCreationWizard"/>
+<new_wizard_action id="org.eclipse.jdt.ui.wizards.NewClassCreationWizard"/>
+<new_wizard_action id="org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"/>
+<new_wizard_action id="org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard"/>
+<new_wizard_action id="org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard"/>
+<new_wizard_action id="org.eclipse.ui.wizards.new.folder"/>
+<new_wizard_action id="org.eclipse.ui.wizards.new.file"/>
+<new_wizard_action id="com.aston.wizards.applet.NewAppletCreationWizard"/>
+<new_wizard_action id="com.aston.wizards.html.NewHtmlCreationWizard"/>
+<new_wizard_action id="com.aston.wizards.jsp.NewJspCreationWizard"/>
+<new_wizard_action id="com.aston.wizards.xhtml.NewXhtmlCreationWizard"/>
+<new_wizard_action id="com.aston.wizards.servlet.NewServletCreationWizard"/>
+<new_wizard_action id="org.jboss.ide.eclipse.jdt.j2ee.ui.wizards.ejb.NewSessionEJBWizard"/>
+<new_wizard_action id="org.jboss.ide.eclipse.jdt.j2ee.ui.wizards.ejb.NewEntityEJBWizard"/>
+<new_wizard_action id="org.jboss.ide.eclipse.jdt.j2ee.ui.wizards.ejb.NewMessageDrivenEJBWizard"/>
+<new_wizard_action id="com.aston.wizards.xml.NewXmlCreationWizard"/>
+<new_wizard_action id="org.eclipse.wst.xml.ui.internal.wizards.NewXMLWizard"/>
+<new_wizard_action id="org.eclipse.wst.xsd.ui.internal.wizards.NewXSDWizard"/>
+<new_wizard_action id="com.genuitec.eclipse.struts.org.easystruts.eclipse.wizards.NewFormCreationWizardX1_1"/>
+<new_wizard_action id="com.genuitec.eclipse.struts.org.easystruts.eclipse.wizards.NewActionCreationWizardX1_1"/>
+<new_wizard_action id="com.genuitec.eclipse.dehory.newformwizard"/>
+<new_wizard_action id="com.genuitec.eclipse.reporting.projectwizard"/>
+<new_wizard_action id="com.genuitec.eclipse.uml.wizard.NewUMLModelFileWizard"/>
+<perspective_action id="com.genuitec.eclipse.dehory.dehoryperspective"/>
+<perspective_action id="com.genuitec.eclipse.hibernate.perspective.HibernatePerspective"/>
+<perspective_action id="com.genuitec.eclipse.imageeditor.perspective"/>
+<perspective_action id="com.genuitec.dali.adapter.persistencePerspective"/>
+<perspective_action id="com.genuitec.eclipse.reporting.ReportPerspective"/>
+<perspective_action id="com.genuitec.eclipse.sqlexplorer.perspectives.SQLExplorerPluginPerspective"/>
+<perspective_action id="com.genuitec.eclipse.uml.umlPerspective"/>
+<perspective_action id="com.genuitec.eclipse.web20.perspective"/>
+<hide_toolbar_item_id id="org.eclipse.jdt.ui.actions.OpenProjectWizard"/>
+<hide_toolbar_item_id id="org.eclipse.ui.edit.text.toggleShowSelectedElementOnly"/>
+<view id="org.eclipse.jdt.ui.PackageExplorer"/>
+<view id="org.eclipse.jdt.ui.TypeHierarchy"/>
+<view id="uky.article.imageviewer.views.ImageView"/>
+<view id="org.eclipse.wst.common.snippets.internal.ui.SnippetsView"/>
+<view id="org.eclipse.ui.views.ContentOutline"/>
+<view id="org.eclipse.ui.views.PropertySheet"/>
+<view id="org.eclipse.ui.views.ProblemView"/>
+<view id="org.eclipse.ui.views.TaskList"/>
+<view id="com.genuitec.eclipse.ui.HTMLView"/>
+<view id="org.eclipse.ui.console.ConsoleView"/>
+<view id="com.genuitec.eclipse.ast.deploy.core.serverview"/>
+<fastViewBars/>
+<layout>
+<mainWindow>
+<info folder="true" part="cvslocation">
+<folder appearance="2" expanded="2">
+<page content="org.eclipse.team.ccvs.ui.RepositoriesView" label="LabelNotFound"/>
+</folder>
+</info>
+<info folder="true" part="stickyFolderRight" ratio="0.75" ratioLeft="750" ratioRight="250" relationship="2" relative="cvslocation">
+<folder appearance="2" expanded="2">
+<page content="org.eclipse.help.ui.HelpView" label="LabelNotFound"/>
+<page content="org.eclipse.ui.internal.introview" label="LabelNotFound"/>
+<page content="org.eclipse.ui.cheatsheets.views.CheatSheetView" label="LabelNotFound"/>
+</folder>
+</info>
+<info part="org.eclipse.ui.editorss" ratio="0.2" ratioLeft="200" ratioRight="800" relationship="2" relative="cvslocation"/>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@2cae38bd" ratio="0.75" ratioLeft="600" ratioRight="200" relationship="2" relative="org.eclipse.ui.editorss">
+<folder activePageID="org.eclipse.ui.views.ContentOutline" appearance="2" expanded="2">
+<page content="org.eclipse.ui.views.ContentOutline" label="Outline"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="org.eclipse.ui.internal.ViewStack@620f1735" ratio="0.54868627" ratioLeft="355" ratioRight="292" relationship="4" relative="org.eclipse.ui.internal.ViewStack@2cae38bd">
+<folder activePageID="org.eclipse.ui.views.PropertySheet" appearance="2" expanded="2">
+<page content="org.eclipse.ui.views.PropertySheet" label="Properties"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="bottom" ratio="0.7496136" ratioLeft="485" ratioRight="162" relationship="4" relative="org.eclipse.ui.editorss">
+<folder activePageID="org.eclipse.ui.views.ProblemView" appearance="2" expanded="2">
+<page content="org.eclipse.ui.views.ProblemView" label="Problems"/>
+<page content="org.eclipse.ui.views.TaskList" label="Tasks"/>
+<page content="com.genuitec.eclipse.ui.HTMLView" label="Web Browser"/>
+<page content="org.eclipse.ui.console.ConsoleView" label="Console"/>
+<page content="com.genuitec.eclipse.ast.deploy.core.serverview" label="Servers"/>
+<page content="org.eclipse.search.ui.views.SearchView" label="LabelNotFound"/>
+<page content="org.eclipse.ui.views.BookmarkView" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+<part id="1"/>
+<part id="2"/>
+<part id="3"/>
+<part id="4"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="topleft" ratio="0.39876354" ratioLeft="258" ratioRight="389" relationship="4" relative="cvslocation">
+<folder activePageID="org.eclipse.jdt.ui.PackageExplorer" appearance="2" expanded="2">
+<page content="org.eclipse.jdt.ui.PackageExplorer" label="Package Explorer"/>
+<page content="org.eclipse.jdt.ui.TypeHierarchy" label="Type Hierarchy"/>
+<page content="org.eclipse.ui.views.ResourceNavigator" label="LabelNotFound"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+<part id="1"/>
+</presentation>
+</folder>
+</info>
+<info folder="true" part="bottomleft" ratio="0.54868627" ratioLeft="355" ratioRight="292" relationship="4" relative="topleft">
+<folder activePageID="uky.article.imageviewer.views.ImageView" appearance="2" expanded="2">
+<page content="uky.article.imageviewer.views.ImageView" label="Image Preview"/>
+<page content="org.eclipse.wst.common.snippets.internal.ui.SnippetsView" label="Snippets"/>
+<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory">
+<part id="0"/>
+<part id="1"/>
+</presentation>
+</folder>
+</info>
+</mainWindow>
+</layout>
+</perspective>
+</perspectives>
+<workingSets/>
+<navigationHistory/>
+<input factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/" type="8"/>
+</page>
+<workbenchWindowAdvisor/>
+<actionBarAdvisor/>
+<trimLayout>
+<trimArea IMemento.internal.id="128">
+<trimItem IMemento.internal.id="org.eclipse.ui.internal.WorkbenchWindow.topBar"/>
+</trimArea>
+<trimArea IMemento.internal.id="1024">
+<trimItem IMemento.internal.id="org.eclise.ui.internal.FastViewBar"/>
+<trimItem IMemento.internal.id="org.eclipse.jface.action.StatusLineManager"/>
+<trimItem IMemento.internal.id="org.eclipse.ui.internal.progress.ProgressRegion"/>
+</trimArea>
+</trimLayout>
+</window>
+<mruList/>
+</workbench>
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
new file mode 100644
index 0000000..188c968
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<workingSetManager>
+<workingSet aggregate="true" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1527837599747_0" label="Window Working Set" name="Aggregate for window 1527837599746"/>
+</workingSetManager>
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.wst.common.snippets/hidden.xml b/.metadata/.plugins/org.eclipse.wst.common.snippets/hidden.xml
new file mode 100644
index 0000000..ab946b8
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.wst.common.snippets/hidden.xml
Binary files differ
diff --git a/.metadata/.plugins/org.eclipse.wst.common.snippets/user.xml b/.metadata/.plugins/org.eclipse.wst.common.snippets/user.xml
new file mode 100644
index 0000000..8c5b84e
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.wst.common.snippets/user.xml
Binary files differ
diff --git a/.metadata/version.ini b/.metadata/version.ini
new file mode 100644
index 0000000..c51ff74
--- /dev/null
+++ b/.metadata/version.ini
@@ -0,0 +1 @@
+org.eclipse.core.runtime=1
\ No newline at end of file
diff --git a/.mymetadata b/.mymetadata
new file mode 100644
index 0000000..c5ce9a0
--- /dev/null
+++ b/.mymetadata
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-module
+  type="WEB"
+  name="frame"
+  id="myeclipse.1527049157387"
+  context-root="/framefile"
+  j2ee-spec="6.0"
+  archive="frame.war">
+  <attributes>
+    <attribute name="webrootdir" value="WebRoot" />
+  </attributes>
+</project-module>
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..ed5807d
--- /dev/null
+++ b/.project
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>framefile</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.genuitec.eclipse.j2eedt.core.WebClasspathBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.genuitec.eclipse.j2eedt.core.J2EEProjectValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.genuitec.eclipse.ast.deploy.core.DeploymentBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.genuitec.eclipse.ast.deploy.core.deploymentnature</nature>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>com.genuitec.eclipse.j2eedt.core.webnature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+	</natures>
+</projectDescription>
diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope
new file mode 100644
index 0000000..252e54f
--- /dev/null
+++ b/.settings/.jsdtscope
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="WebRoot"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+		<attributes>
+			<attribute name="hide" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+	<classpathentry kind="output" path=""/>
+</classpath>
diff --git a/.settings/com.genuitec.eclipse.core.prefs b/.settings/com.genuitec.eclipse.core.prefs
new file mode 100644
index 0000000..626a309
--- /dev/null
+++ b/.settings/com.genuitec.eclipse.core.prefs
@@ -0,0 +1,4 @@
+#Mon May 28 15:27:12 CST 2018
+eclipse.preferences.version=1
+validator.Checked=WebRoot/js/jquery-1.7.2.min.js
+validator.Unchecked=
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b3cdf4f
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed May 23 12:19:24 CST 2018
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..58534e5
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="framefile">
+        <wb-resource deploy-path="/" source-path="/WebRoot"/>
+        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
+        <property name="context-root" value="/framefile"/>
+        <property name="java-output-path" value="/framefile/WebRoot/WEB-INF/classes"/>
+    </wb-module>
+</project-modules>
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..5a88726
--- /dev/null
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+  <fixed facet="wst.jsdt.web"/>
+  <installed facet="java" version="1.6"/>
+  <installed facet="jst.web" version="3.0"/>
+  <installed facet="wst.jsdt.web" version="1.0"/>
+</faceted-project>
diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/WebRoot/META-INF/MANIFEST.MF b/WebRoot/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..254272e
--- /dev/null
+++ b/WebRoot/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+
diff --git a/WebRoot/WEB-INF/web.xml b/WebRoot/WEB-INF/web.xml
new file mode 100644
index 0000000..16d4d82
--- /dev/null
+++ b/WebRoot/WEB-INF/web.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="3.0" 
+	xmlns="http://java.sun.com/xml/ns/javaee" 
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
+	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+  <display-name></display-name>	
+  <welcome-file-list>
+    <welcome-file>index.jsp</welcome-file>
+  </welcome-file-list>
+</web-app>
diff --git a/WebRoot/css/card.css b/WebRoot/css/card.css
new file mode 100644
index 0000000..9c31825
--- /dev/null
+++ b/WebRoot/css/card.css
@@ -0,0 +1,71 @@
+锘�.datacard table {
+	width: 100%;
+}
+.datacard tr {
+	
+}
+.datacard th {
+	background-color: #f3eded;
+	width: 100px;
+	text-align: center;
+}
+.datacard td {
+	width: 200px;
+}
+
+.datacard_group {
+	height: 20px;
+}
+
+.datacard_cell {
+	height: 32px;
+}
+
+.datacard th, .datacard td{
+	border: 1px solid #dcc7c7;
+}
+.datacard input {
+	width: 98%;
+	height: 100%;
+	border: none;
+	padding-left: 2%;
+}
+
+.datacard select {
+	width: 100%;
+	height: 100%;
+	border: none;
+	padding-left: 5%;
+}
+
+.datacard_value_editor {
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	right: 28px;
+	bottom: 1px;
+}
+
+.datacard_value_validator {
+	position: absolute;
+	right: 0px;
+	top: 0px;
+	width: 28px;
+	height: 100%;
+	padding-top: 5px;
+	cursor: pointer;
+}
+
+.datacard_title {
+	margin-top: 3px;
+	margin-left: 20px;
+	height: 20px;
+	font-style: italic;
+	text-align: left;
+}
+
+.datacard_title_img {
+	height: 18px; 
+	float: left;
+	margin-right: 5px;
+}
\ No newline at end of file
diff --git a/WebRoot/css/demo.css b/WebRoot/css/demo.css
new file mode 100644
index 0000000..4c5f0b6
--- /dev/null
+++ b/WebRoot/css/demo.css
@@ -0,0 +1,50 @@
+@CHARSET "UTF-8";
+
+body {
+	margin: 0px;
+}
+
+.list {
+	position: absolute;
+	left: 0px;
+	width: 20%;
+	top: 0px;
+	bottom: 0px;
+	background-color: #fbfafa;
+	font-size: 14px;
+}
+
+.content {
+	position: absolute;
+	top: 0px;
+	bottom: 0px;
+	left: 20%;
+	right: 0px;
+	font: 13px;
+}
+
+.list-header {
+	height: 40px;
+	line-height: 40px;
+	padding-left: 30px;
+	background-color: #e3e3e3;
+}
+
+.list-line {
+	height: 30px;
+	line-height: 30px;
+	padding-left: 40px;
+	cursor: pointer;
+}
+
+.list-line:HOVER {
+	background-color: #f8ebeb;
+}
+
+.card {
+	float: left;
+	width: 17%;
+	height: 150px;
+	margin: 2% 2% 0px 0px;
+	border: 1px solid #e3e3e3;
+}
\ No newline at end of file
diff --git a/WebRoot/css/dialog.css b/WebRoot/css/dialog.css
new file mode 100644
index 0000000..c0523af
--- /dev/null
+++ b/WebRoot/css/dialog.css
@@ -0,0 +1,154 @@
+/************************ dialog *************************/
+.dialog_mask {
+	position: fixed;
+	z-index: 900;
+	top: 0px;
+	left: 0px;
+	width: 100%;
+	height: 100%;
+	transform: translateY(0);
+	background: rgba(0, 0, 0, 0.5);
+}
+
+.dialog {
+	background-color: white;	
+	width: 80%;
+	max-width: 360px;
+	margin-top: 100px;
+	text-align: left;
+}
+.dialog_header {
+	height: 28px;
+	line-height: 28px;
+	background-color: #EFEFEF;
+	color: #1366CB;
+	font-size: 14px;
+	font-weight: bold;
+	border-bottom: #C7B2B2 1px dotted;
+	border-top: #C7B2B2 1px dotted;
+	padding-left: 10px;
+
+}
+
+.dialog_body {
+	height: 55px;
+}
+
+.databox_body {
+	height: 95px;
+}
+
+.dialog_content {
+	margin: 15px 0px 20px 20px;
+	width: 90%;
+	height: 40px;
+	line-height: 40px;
+}
+
+.databox_content {
+	margin: 0px 0px 20px 20px;
+	width: 90%;
+	height: 40px;
+	line-height: 40px;
+}
+
+.dialog_image {
+	float: left;
+	width: 28px;
+	height: 28px;
+	background-size: 100%;
+	margin: 4px 10px 0px 0px
+}
+
+.databox_image {
+	float: left;
+	width: 28px;
+	height: 28px;
+	background-size: 100%;
+	margin: 4px 10px 0px 0px;
+	background-image: url("../image/dialog/confirm.png");
+}
+
+.icon_confirm {
+	background-image: url("../image/dialog/confirm.png");
+	background-repeat: no-repeat;
+}
+
+.icon_alert {
+	background-image: url("../image/dialog/alert.png");
+	background-repeat: no-repeat;
+}
+
+.dialog_text {
+	color: #1366CB;
+	font-size: 14px;
+}
+
+.databox_text {
+	color: #1366CB;
+	font-size: 14px;
+	text-align: center;
+}
+
+.dialog_footer {
+	padding: 8px 50px 8px 0px;
+	text-align: right;
+	border-top: #C7B2B2 1px dotted;
+}
+
+.databox_footer {
+	margin-top: 10px;
+	padding: 8px 50px 8px 0px;
+	text-align: right;
+	border-top: #C7B2B2 1px dotted;
+}
+
+.gm_body {
+	margin-bottom:5px;
+	overflow:hidden;
+}
+
+.gm_header {
+	height: 38px;
+	cursor: pointer;
+	min-width: 150px;
+}
+
+.gm_header_indicator {
+	float: left;
+	width: 8px;
+	height: 100%;
+}
+
+.gm_header_img {
+	float: left;
+	margin: 7px 5px 0 0;
+	height: 20px;
+	margin-left: 10%;
+}
+
+.gm_header_text {
+	float:left;
+	height:100%;
+	line-height: 35px;
+}
+
+.gm_menu {
+	height:38px;
+	padding-left:35px;
+	cursor: pointer;
+	display:none;
+	min-width: 150px;
+}
+
+.gm_menu_img {
+	float: left;
+	margin: 7px 8px 0 8px;
+	width: 20px;
+}
+
+.gm_menu_text {
+	float:left;
+	height:100%;
+	line-height: 35px;
+}
\ No newline at end of file
diff --git a/WebRoot/css/grid.css b/WebRoot/css/grid.css
new file mode 100644
index 0000000..844a1c6
--- /dev/null
+++ b/WebRoot/css/grid.css
@@ -0,0 +1,272 @@
+body {
+  	margin: 0px;
+  	background-color: white;
+}
+
+/* --------------* grid * ------------ */
+.grid {
+	position: relative;
+	border: 1px solid #A3C0E8;
+	font-size: 13px;
+	font-family: 寰蒋闆呴粦;	
+}
+
+.grid-header {
+	line-height: 30px;
+	height: 30px;
+	width: 100%;
+	background: #E2F0FF url('root/image/control/grid-header-bg.gif') repeat-x left bottom;
+	border-bottom: 1px solid #A3C0E8;
+	font-size: 14px;
+}
+
+.grid-body {
+	/*overflow-y: scroll;*/
+	font-size: 14px;
+	overflow-y: hidden; 
+	overflow-x: hidden;
+}
+
+.grid-body_min {
+	font-size: 14px;
+	overflow: auto; 
+}
+
+.l-grid-row {
+	height: 28px;
+}
+
+.grid-row-over {
+	background: #E0ECFF
+}
+
+.grid-row-selected {
+	background: #DCF8A8
+}
+
+.grid-indicator {
+	padding: 0;
+	margin: 0;
+	overflow: hidden;
+	border-right: 1px solid #A3C0E8;
+	border-bottom: 1px solid #A3C0E8;
+}
+
+.grid-indicator-unselected {
+	background-image: url("root/image/control/grid-checkbox.gif");
+	background-repeat: no-repeat;
+	background-position: 9px 7px;
+}
+
+.grid-indicator-selected {
+	background-image: url("root/image/control/grid-checkbox-checked.gif");
+	background-repeat: no-repeat;
+	background-position: 9px 7px;
+}
+
+.grid-hd-cell {
+	padding: 0;
+	margin: 0;
+	overflow: hidden;
+	border-right: 1px solid #A3C0E8;
+	border-bottom: 1px solid #A3C0E8;
+	text-align: center;
+	cursor: pointer;
+}
+
+.grid-hd-cell-inner {
+	text-align: center;
+	padding-right: 4px;
+	padding-left: 4px;
+}
+
+.grid-hd-indicator-inner {
+	height: 26px;
+	line-height: 26px;
+	text-align: center;
+	padding-right: 4px;
+	padding-left: 4px;
+}
+
+.grid-hd-cell-text {
+	text-align: center;
+	cursor: pointer;
+}
+
+.grid-cell {
+	overflow: hidden;
+	border-right: 1px solid #A3C0E8;
+	border-bottom: 1px solid #A3C0E8;
+	text-align: center;
+	overflow: hidden;
+}
+
+.grid-cell-inner {
+	height: 27px;
+	line-height: 27px;
+	padding-right: 4px;
+	padding-left: 4px;
+	overflow: hidden;
+	position: relative;
+}
+
+.grid-bar {
+	height: 30px;
+	background: #C9DFFF;
+	overflow: hidden;
+	border-top: 1px solid #A3C0E8;
+}
+
+.grid-bar-placeholder {
+	float: left;
+	height: 28px;
+	line-height: 28px;
+	width: 120px;
+	text-align: right;
+	padding: 0px 20px 0px 0px;
+	font-style: italic;
+	font-family: 骞煎渾;
+	font-size: 13px;
+	text-align:center;
+}
+
+.grid-bar-area {
+	float: left;
+	border-left: 1px solid #A3C0E8;
+	border-right: 1px solid #A3C0E8;
+	width: 280px
+}
+
+.grid-bar-group {
+	float: left;
+	height: 24px;
+	margin: 4px 5px 0px 20px;
+}
+
+.grid-button-outer {
+	float: left;
+	width: 22px;
+	height: 22px;
+	border: 0px;
+	margin: 1px 2px 0px 2px;
+	cursor: pointer;
+	overflow: hidden;
+}
+
+.grid-button-over {
+	background: url(root/image/control/bar-button-over.gif) no-repeat center;
+}
+
+.grid-button {
+	width: 16px;
+	height: 16px;
+	display: block;
+	margin-left: 2px;
+	margin-top: 2px;
+	float: left;
+	overflow: hidden;
+}
+
+.grid-btn-first {
+	background: url(root/image/control/icon-first.gif) no-repeat;
+	background-position: 0px 0px;
+}
+
+.grid-btn-prior {
+	background: url(root/image/control/icon-prev.gif) no-repeat;
+	background-position: 0px 0px;
+}
+
+.grid-btn-next {
+	background: url(root/image/control/icon-next.gif) no-repeat;
+	background-position: 0px 0px;
+}
+
+.grid-btn-last {
+	background: url(root/image/control/icon-last.gif) no-repeat;
+	background-position: 0px 0px;
+}
+
+.grid-btn-load {
+	background: url(root/image/control/icon-load.gif) no-repeat;
+}
+
+.grid-btn-disable {
+	background-position: 0px -16px;
+}
+
+.grid-bar-edit {
+	width: 24px;
+	margin: 3px 2px 0px 2px;
+	height: 14px;
+	line-height: 16px;
+	border: #969696 solid 1px;
+}
+
+.grid-bar-label {
+	width: 30px;
+	text-align: right;
+	margin: 3px 2px 3px 2px;
+}
+
+.grid-bar-edit {
+	width: 30px;
+	margin: 2px 2px 0px 2px;
+	padding: 2px 0px 1px 4px;
+	height: 14px;
+	line-height: 16px;
+	border: #969696 solid 1px;
+}
+
+.grid-message {
+	position: absolute;
+	right: 20px;
+}
+
+.grid-message-text {
+	line-height: 24px;
+	margin-top: 4px;
+}
+
+.tab_self {
+	display: inline-flex;
+	display: inline-block;
+	flex-flow: column;
+	width: 100%;
+	height: 100%;
+}
+
+.tab_self_min {
+	display: inline-flex;
+	display: inline-block;
+	flex-flow: column;
+	width: 100%;
+}
+
+.tab_self_header {
+	display:block;
+	overflow-x:hidden; 
+	overflow-y:scroll; 
+	width:100%;
+	font-weight: 500;
+}
+
+.tab_self_header_min {
+	display:block;
+	width:100%;
+	font-weight: 500;
+}
+
+.tab_self_body {
+	display:block; 
+	overflow-y:scroll; 
+	overflow-x:auto; 
+	width:100%;
+	flex:1;
+}
+
+.tab_self_body_min {
+	display:block; 
+	width:100%;
+	flex:1;
+}
\ No newline at end of file
diff --git a/WebRoot/css/home.css b/WebRoot/css/home.css
new file mode 100644
index 0000000..3be925f
--- /dev/null
+++ b/WebRoot/css/home.css
@@ -0,0 +1,50 @@
+@CHARSET "UTF-8";
+
+body {
+	margin: 0px;
+}
+
+.header {
+	height: 220px;
+	background-image: url("../image/bg.jpg");
+	color: white;
+}
+
+.header-title {
+	padding-top: 30px;
+	text-align: center;
+	font: 28px 寰蒋闆呴粦;
+}
+
+.header-subtitle {
+	padding-top: 30px;
+	text-align: center;
+	font: 20px 寰蒋闆呴粦;
+}
+
+.header-button {
+	display: inline-block;
+	height: 36px;
+	line-height: 36px;
+	width: 160px;
+    color: #fff;
+    background-color: #429842;
+    border-color: #429842;
+    border-radius: 6px;
+}
+	
+.article {
+	margin: 20px 80px;
+	font: 15px 寰蒋闆呴粦;
+}
+
+.article-title {
+	font-weight: bold;
+	height: 28px;
+	line-height: 28px;
+}
+
+.article-line {
+	height: 28px;
+	line-height: 28px;
+}
diff --git a/WebRoot/css/loading.css b/WebRoot/css/loading.css
new file mode 100644
index 0000000..415eeb0
--- /dev/null
+++ b/WebRoot/css/loading.css
@@ -0,0 +1,45 @@
+/*********************** loading ************************/
+.loading_mask {
+	position: fixed;
+	z-index: 600;
+	top: 0px;
+	left: 0px;
+	width: 100%;
+	height: 100%;
+	transform: translateY(0);
+	background: rgba(255, 255, 255, 0.6);
+}
+
+.loading_area {
+	display: inline-block;
+	max-width: 240px;
+	margin: 200px 0px 0px 0px;
+	border-radius: 15px;
+	background-color: rgba(0, 0, 0, 0.6);
+	font-size: 14px;
+	padding-left: 20px;
+	padding-right: 20px;
+	padding: 10px 20px 10px 20px;
+	color: #FFFFFF;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+}
+
+.loading_image {
+	width: 32px;
+	height: 32px;
+	background-image: url(../image/loading.gif);
+	background-size: 32px 32px;
+	background-repeat: no-repeat;
+	background-position: 0px 0px;
+	margin-bottom: 10px;	
+}
+
+.loading_text {
+	position: relative;
+	height: 24px;
+	line-height: 24px;
+	text-align: center;
+	font-size: 14px;
+}
diff --git a/WebRoot/css/main.css b/WebRoot/css/main.css
new file mode 100644
index 0000000..cd75d6d
--- /dev/null
+++ b/WebRoot/css/main.css
@@ -0,0 +1,38 @@
+@CHARSET "UTF-8";
+
+body {
+	overflow: hidden;
+}
+
+.header {
+	position: absolute;
+	height: 45px;
+	left: 0px;
+	right: 0px;
+	top: 0px;
+	background-color: #222;
+	font: 15px 寰蒋闆呴粦;
+}
+
+.header-button {
+	float: left;
+	width: 8%;
+	height: 44px;
+	line-height: 44px;
+	color: white;
+	text-align: center;
+	cursor: pointer;
+}
+
+.header-button:HOVER {
+	background-color: #9f7b7b;
+}
+
+.content {
+	position: absolute;
+	top: 45px;
+	left: 0px;
+	bottom: 0px;
+	right: 0px;
+	font: 13px;
+}
\ No newline at end of file
diff --git a/WebRoot/css/tree.css b/WebRoot/css/tree.css
new file mode 100644
index 0000000..586d754
--- /dev/null
+++ b/WebRoot/css/tree.css
@@ -0,0 +1,194 @@
+锘�
+.tree {
+	border: 1px solid #C9DFFF;
+	overflow: auto;	
+	white-space: nowrap;
+}
+
+.tree-inner {
+}
+
+.tree-body {
+	margin: 0;
+	padding: 0;
+	list-style: none;
+/* 	overflow: hidden; */
+	position: relative;
+	display: block;
+	background: white;
+}
+
+.tree-body-loading {
+	position: absolute;
+	z-index: 91000;
+	top: 40%;
+	left: 50%;
+	overflow: hidden;
+	background: url('../image/tree/loading.gif') no-repeat 0px 0px;
+	width: 24px;
+	height: 24px;
+	display: none;
+}
+
+.tree-body ul,.tree-body li {
+	list-style: none;
+	margin: 0;
+	padding: 0;
+}
+
+.tree-body li .l-body {
+	height: 22px;
+	line-height: 22px;
+	/* overflow: hidden; */
+}
+
+.tree-body .l-box {
+	width: 22px;
+	height: 22px;
+	overflow: hidden;
+	float: left;
+	background: url('../image/tree/tree.gif');
+	background-position: -22px -220px;
+}
+
+.tree-body-noline .l-box {
+	background-image: url('../image/tree/tree-noline.gif');
+}
+
+.tree-body .l-expandable-close {
+	background-position: 0px -44px;
+}
+
+.tree-body .l-first .l-expandable-close {
+	background-position: 0px -22px;
+}
+
+.tree-body .l-last .l-expandable-close {
+	background-position: 0px -66px;
+}
+
+.tree-body .l-last li .l-expandable-close {
+	background-position: 0px -44px;
+}
+
+.tree-body .l-onlychild  .l-expandable-close {
+	background-position: 0px 0px;
+}
+
+
+.tree-body .l-onlychild li .l-expandable-close {
+	background-position: 0px -44px;
+}
+
+.tree-body .l-onlychild .l-last > div > .l-expandable-close {
+	background-position: 0px -66px;
+}
+
+.tree-body .l-expandable-open {
+	background-position: 0px -132px;
+}
+
+.tree-body .l-first .l-expandable-open {
+	background-position: 0px -110px;
+}
+
+.tree-body .l-last .l-expandable-open {
+	background-position: 0px -154px;
+}
+
+.tree-body .l-onlychild  .l-expandable-open {
+	background-position: 0px -88px;
+}
+.tree-body .l-onlychild li .l-expandable-open {
+	background-position: 0px -132px;
+}
+
+.tree-body .l-onlychild .l-last > ul > li > .l-expandable-open {
+	background-position: 0px -132px;
+}
+.tree-body .l-onlychild .l-last > div > .l-expandable-open {
+	background-position: 0px -154px;
+}
+
+.tree-body .l-over {
+	background: whiteSmoke;
+}
+
+.tree-body .l-selected {
+	background: #D9E8FB;
+}
+
+.tree-body .l-line {
+	background-position: 0px -176px;
+}
+
+.tree-body .l-note {
+	background-position: 0px -198px;
+}
+
+.tree-body .l-note-last {
+	background-position: 0px -220px;
+}
+
+.tree-body .l-checkbox-unchecked {
+	background-position: -22px 0px;
+}
+
+.tree-body .l-checkbox-checked {
+	background-position: -22px -22px;
+}
+
+.tree-body .l-checkbox-incomplete {
+	background-position: -22px -44px;
+}
+
+.tree-body .l-over .l-checkbox-unchecked {
+	background-position: -44px 0px;
+}
+
+.tree-body .l-over .l-checkbox-checked {
+	background-position: -44px -22px;
+}
+
+.tree-body .l-over .l-checkbox-incomplete {
+	background-position: -44px -44px;
+}
+
+.tree-body .tree-body-icon-folder {
+	background-position: -22px -88px;
+}
+
+.tree-body .tree-body-icon-none {
+	background: none;
+}
+
+.tree-body .tree-body-icon-none img {
+	width: 22px;
+	height: 22px;
+	border: 0;
+}
+
+.tree-body .tree-body-icon-folder-open {
+	background-position: -44px -88px;
+}
+
+.tree-body .tree-body-icon-leaf {
+	background-position: -22px -110px;
+}
+
+.tree-body .l-last li .l-expandable-open {
+	background-position: 0px -132px;
+}
+
+.node {
+	padding: 2px 4px 2px 4px;
+	cursor: pointer;
+}
+
+.node:HOVER {
+	background-color: #dcc7c7
+}
+	
+.node-selected {
+	background-color: #C9DFFF;
+}
\ No newline at end of file
diff --git a/WebRoot/image/tree/tree-leaf.gif b/WebRoot/image/tree/tree-leaf.gif
new file mode 100644
index 0000000..9e4f2a6
--- /dev/null
+++ b/WebRoot/image/tree/tree-leaf.gif
Binary files differ
diff --git a/WebRoot/image/tree/tree-level.gif b/WebRoot/image/tree/tree-level.gif
new file mode 100644
index 0000000..9e4f2a6
--- /dev/null
+++ b/WebRoot/image/tree/tree-level.gif
Binary files differ
diff --git a/WebRoot/image/tree/tree-noline.gif b/WebRoot/image/tree/tree-noline.gif
new file mode 100644
index 0000000..7cd6780
--- /dev/null
+++ b/WebRoot/image/tree/tree-noline.gif
Binary files differ
diff --git a/WebRoot/image/tree/tree-status-close.gif b/WebRoot/image/tree/tree-status-close.gif
new file mode 100644
index 0000000..01ef0a9
--- /dev/null
+++ b/WebRoot/image/tree/tree-status-close.gif
Binary files differ
diff --git a/WebRoot/image/tree/tree-status-open.gif b/WebRoot/image/tree/tree-status-open.gif
new file mode 100644
index 0000000..a959cd9
--- /dev/null
+++ b/WebRoot/image/tree/tree-status-open.gif
Binary files differ
diff --git a/WebRoot/image/tree/tree-status.gif b/WebRoot/image/tree/tree-status.gif
new file mode 100644
index 0000000..dde337a
--- /dev/null
+++ b/WebRoot/image/tree/tree-status.gif
Binary files differ
diff --git a/WebRoot/image/tree/tree.gif b/WebRoot/image/tree/tree.gif
new file mode 100644
index 0000000..b50dcb7
--- /dev/null
+++ b/WebRoot/image/tree/tree.gif
Binary files differ
diff --git a/WebRoot/index.jsp b/WebRoot/index.jsp
new file mode 100644
index 0000000..0866042
--- /dev/null
+++ b/WebRoot/index.jsp
@@ -0,0 +1,26 @@
+<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
+<%
+String path = request.getContextPath();
+String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
+%>
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <base href="<%=basePath%>">
+    
+    <title>My JSP 'index.jsp' starting page</title>
+	<meta http-equiv="pragma" content="no-cache">
+	<meta http-equiv="cache-control" content="no-cache">
+	<meta http-equiv="expires" content="0">    
+	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
+	<meta http-equiv="description" content="This is my page">
+	<!--
+	<link rel="stylesheet" type="text/css" href="styles.css">
+	-->
+  </head>
+  
+  <body>
+    This is my JSP page. <br>
+  </body>
+</html>
diff --git a/WebRoot/js/card.js b/WebRoot/js/card.js
new file mode 100644
index 0000000..2456447
--- /dev/null
+++ b/WebRoot/js/card.js
@@ -0,0 +1,339 @@
+(function ($) {
+	DataObject = Object.subClass({
+		init: function(data) {
+			this.record = data || {};
+			this.old = {};
+			this.changed = false;
+			
+			Object.call(this, {});
+		},		
+		
+		setValue: function(prop, value) {
+			this.record[prop] = value;
+			
+			if (this.old[prop] != this.record[prop]) {
+				this.changed = true;
+			}
+			
+			if (this.onDataChange) {
+				this.onDataChange();
+			}
+		},
+		
+		getValue: function(prop) {
+			return this.record[prop];
+		},
+		
+		valueChanged: function(prop) {
+			return this.old[prop] != this.record[prop];
+		},
+
+		commit: function() {
+			this.old = $.extend({}, this.record);
+			this.changed = false;	
+		}
+	});
+	
+	Card = $.fm.Card = Control.subClass({
+		template: [
+		    '<table class="datacard">',  
+			'</table>'
+		],
+		template_title: [
+		    '<tr>',
+		    	'<td id="title_body" class="datacard_group">',
+		    		'<div class="datacard_title"><img class="datacard_title_img" src="../../../image/detail.png"><label id="lbl_title"></label></div>',
+		    	'</td>',
+		    '</tr>'
+		],
+		template_line: '<tr></tr>',
+		template_line_validate: '<tr><td id="cell" class="datacard_group"><div></div></td></tr>',
+		template_key: '<th class="datacard_cell datacard_key"></th>',
+		template_value: [
+		    '<td class="datacard_cell datacard_value">',
+		    	'<div style="position: relative; width: 100%; height: 100%">',
+		    		'<div id="value" class="datacard_value_editor"></div>',
+		    		'<div id="validator" class="Validform_checktip datacard_value_validator"></div>',
+		    	'</div>',
+		    '</td>'
+		    ],
+		template_validate: '<td><label class="Validform_checktip"></label></td>',
+		template_editor: '<input>', 
+		template_select: '<select></select>',
+		template_select_option: '<option></option>',
+		    		
+		init: function(options) {
+			this.linkElement = null;
+			this.editClasss = ["input", "textarea"];
+			this.editable = false;
+			this.columns = [];
+			this.editors = {};
+			this.tiptype = 2;
+			this.columnCount = 1;
+			this.cellCount = 0;
+			this.columnPosition = 0;
+			this.currentLine = null;
+			this.dataObject = new DataObject();
+			
+			Control.call(this, options);
+			
+			this.createElements();
+    		if (this.linkElement) {
+    			this.collectElements();
+    		}
+    		
+			if (this.url) {
+    			var me = this;
+				Server.getData(this.url, function(data) {
+					Loading.hide();
+					
+					if (me.onGetData) {
+						data = me.onGetData(data);
+					}
+					me.setData(data);
+				});				
+			}
+			else if (this.data) {
+				this.setData(this.data);
+			}
+		},
+		
+		createElements: function() {
+    		var me = this;
+    		
+    		this.canvas.addClass("datacard");
+    		var body = this.body = $(this.template.join(""));
+    		
+    		this.columnCount > 1 ? (this.cellCount = this.columnCount * 2) : (this.cellCount = 3);
+    		
+    		if (this.columnCount > 1) {
+				var validateLine = $(this.template_line_validate);
+				$("#cell", validateLine).attr("colspan", this.cellCount);
+				this.body.append(validateLine);   	
+    		}
+    		
+    		var tableLine = null;
+    		for (var i = 0; i < this.columns.length; i++) {
+    			var column = this.columns[i];
+    			column.index = i;
+    			column.span = column.span || 1;
+    			tableLine = this.createOneColumn(tableLine, column);
+    		}
+    		
+    		if (this.columnPosition > 0 && this.columnPosition < this.columnCount) {
+    			for (var i = this.columnPosition; i <= this.columnCount; i++) {
+    				var column = {span: 1};
+    				tableLine = this.createOneColumn(tableLine, column);
+    			}
+    		}
+    		if(body.Validform) {
+    			body.Validform({
+        			tiptype: this.tiptype
+        		});
+    		}
+    		
+    		this.canvas.append(body);
+		},
+		
+		createOneColumn: function(tableLine, column) {
+			var me = this;
+			
+			//1. create title
+			if (column.group) {
+				var title = $(this.template_title.join(""));
+				$("#lbl_title", title).html(column.group);
+				$("#title_body", title).attr("colspan", this.cellCount);
+				
+				this.body.append(title);
+				this.columnPosition = 0;
+			}
+			
+			//2. create row
+			if ((this.columnPosition == 0) || (this.columnPosition >= this.columnCount)) {
+				tableLine = this.currentLine = $(this.template_line);
+				tableLine.cells = [];
+				
+				this.body.append(tableLine);
+				this.columnPosition = 0;
+			}
+			
+			//2. create column
+			var cell = {};
+			tableLine.cells.push(cell);
+			
+			//2.1
+			cell.key = $(this.template_key);
+			if (column.caption) {
+				cell.key.html(column.caption);
+			}
+			tableLine.append(cell.key);
+			
+			//2.2
+			var content = $(this.template_value.join(""));
+			cell.value = $("#value", content);
+			cell.validator = $("#validator", content);
+			cell.validator.click(function() {
+				var el = $(this);
+				var message = $(".Validform_checktip", el);
+				if(message.html() != null && message.html() != "") {
+					alert(message.html());
+				}
+			});
+			
+			if (column.span > 1) {
+				content.attr("colspan", column.span * 2 - 1);
+			}
+			this.columnPosition = this.columnPosition + column.span;
+			
+			if (column.field) {
+				var editor = ControlCreator.create(column, this);
+				editor.onValueChange = function() {
+					if (me.onValueChange) {
+						me.onValueChange.call(me);
+					}
+				}
+				
+				this.editors[column.field] = editor;
+			}
+			
+			editor.appendTo(cell.value);
+			tableLine.append(content);
+			
+			return tableLine;
+		},
+		
+		collectElements: function() {
+			var linkElement = this.getEl(this.linkElement);
+			if (!linkElement) return;
+			
+			for (var no in this.editClasss) {
+				var editClass = this.editClasss[no];
+				var valueEl = $(editClass, linkElement);
+				this.linkTo(valueEl, this.editors);
+			}
+			
+			var valueEl = $("select", linkElement);
+			this.linkTo(valueEl, this.editors);
+			
+			var valueEl = $("label", linkElement);
+			this.linkTo(valueEl, this.editors);
+
+			var valueEl = $("div", linkElement);
+			this.linkTo(valueEl, this.editors);
+			
+			var valueEl = $("img", linkElement);
+			this.linkTo(valueEl, this.editors);			
+		},
+		
+		linkTo: function(valueEl, link) {
+			for (var i = 0; i < valueEl.length; i++) {
+				var item = $(valueEl.get(i));
+				
+				var fieldname = item.attr("field");
+				if (!fieldname) { fieldname = item.attr("name")}
+				
+				if (fieldname) {
+					fieldname = fieldname.toLowerCase();
+					link[fieldname] = item;
+				}
+			}
+		},
+		
+		setData: function(line) {
+			var dataObject = this.dataObject;
+			
+			dataObject.record = line;
+			dataObject.old = $.extend({}, line);
+			dataObject.changed = false;
+			
+		//	console.log(JSON.stringify(line));
+			
+			for (var prop in line) {
+				var editor = this.editors[prop];
+				
+				if (editor) {
+					editor.setValue ? editor.setValue(line[prop]) : editor.val(line[prop]);
+				}
+			}
+		},
+		
+			setValue: function(field, value) {
+				var dataObject = this.dataObject;
+				
+				var oldValue = dataObject.getValue(field);
+				if (oldValue == value) {
+					return;
+				}
+				
+				dataObject.setValue(field, value);
+				
+				var editor = this.editors[field];
+				if (editor) {
+					editor.setValue ? editor.setValue(value) : editor.val(value);
+				}
+				
+				if (this.onValueChange) {
+					this.onValueChange();
+				}
+			},		
+			
+		getData: function() {
+			var record = this.dataObject.record, old = this.dataObject.old;
+			
+			for (var prop in this.editors) {
+				var editor = this.editors[prop];
+				record[prop] = editor.getValue ? editor.getValue() : editor.val();
+			}
+			
+			for (var prop in record) {
+				if (old[prop] != record[prop]) {
+					this.dataObject.changed = true;
+					break;
+				}
+			}
+			
+			return this.dataObject;
+		},
+		
+		commit: function() {
+			this.dataObject.commit();
+		},
+		
+		getEditByField: function(field) {
+			return this.editors[field];
+		},
+		
+		setReadOnly: function(prop, value) {
+			if (typeof prop == "string") {
+				var editor = this.editors[prop];
+				editor.setReadOnly(value);
+			}
+			else {
+				value = prop;
+				
+				for (var prop in this.editors) {
+					var editor = this.editors[prop];
+					editor.setReadOnly(value);
+				}
+			}
+		},
+		
+		notify: function(event) {
+			var column = this.columns[event.senderKey];
+			if (!column) {
+				return;
+			}
+			
+			var reciver = column[event.name];
+			if (reciver) {
+				reciver(event.newValue, event.record, column, this);
+			}
+		},
+		
+		empty: function() {
+			this.canvas.empty();
+		}
+	
+	});
+	
+})(jQuery);
\ No newline at end of file
diff --git a/WebRoot/js/control.js b/WebRoot/js/control.js
new file mode 100644
index 0000000..509bb9e
--- /dev/null
+++ b/WebRoot/js/control.js
@@ -0,0 +1,2751 @@
+(function ($) {
+	
+	//================================ControlCreator===================================//
+	ControlCreatorClass = $.fm.ControlCreatorClass = Object.subClass({
+		template: {
+			"input": "<input type='text' />",
+			"month": "<input type='month' />",
+			"date": "<input type='date' />",
+			"datetime": "<input type='datetime' />",
+			"time": "<input type='time' />",
+			"number": "<input type='number' />",
+			"select": "<select ></select>",
+			"label": "<label />"
+		},
+	
+		create: function(config, parent) {
+			code = (config.type || "edit").toLowerCase();
+			var result = null;
+			
+			if ("input" == code) {
+				result = this.createInput(config);
+			}
+			else if ("month" == code) {
+				result =  this.createMonthEditor(config);
+			}
+			else if ("date" == code) {
+				result =  this.createDateEditor(config);
+			}
+			else if ("datetime" == code) {
+				result =  this.createDateTimeEditor(config);
+			}
+			else if ("time" == code) {
+				result =  this.createTimeEditor(config);
+			}
+			else if ("number" == code) {
+				result =  this.createNumberEditor(config);
+			}
+			else if ("select" == code) {
+				result =  this.createSelect(config);
+			}
+			else if ("popup" == code) {
+				result =  this.createPopup(config);
+			}
+			else {
+				result =  this.createInput(config);
+			}
+			
+			if (typeof config.readonly != "undefined") {
+				result.setReadOnly(config.readonly, true);
+			}
+			
+			if (result.publishEvents) {
+				result.publishEvents(parent);
+			}
+			
+			return result;
+		},
+		
+		createInput: function(config) {
+			var editor = $(this.template.input);
+			editor.attr("datatype", config.datatype);
+			editor.attr("errormsg", config.errormsg);
+			editor.val(config.defaultValue);
+			editor.setValue = function(value) { this.val(value);}
+			editor.getValue = function() {return this.val() == "" ? null : this.val(); }
+			editor.appendTo = function(parent) { parent.append(this); }
+			editor.setReadOnly = function(value, force) {
+				if (!force && (typeof editor.forceReadonly != "undefined")) {
+					return;
+				}
+				
+				editor.forceReadonly = force;
+				
+				if (value) {
+					editor.attr("readonly", "readonly");
+				}
+				else {
+					editor.removeAttr("readonly");
+				}				
+			}
+			editor.change(function() {
+				if (editor.onValueChange) {
+					editor.onValueChange();
+				}
+			});
+			return editor;
+		},
+		
+		createMonthEditor: function(config) {
+			var config = $.extend({	element: $(this.template.month) }, config);
+			var editor = new DateEditor(config);
+			return editor;
+		},
+		
+		createDateEditor: function(config) {
+			var config = $.extend({	element: $(this.template.date) }, config);
+			var editor = new DateEditor(config);
+			return editor;
+		},
+		
+		createDateTimeEditor: function(config) {
+			var config = $.extend({	element: $(this.template.datetime) }, config);
+			var editor = new DateEditor(config);
+			return editor;
+		},
+		
+		createTimeEditor: function(config) {
+			var config = $.extend({	element: $(this.template.time) }, config);
+			var editor = new DateEditor(config);
+			return editor;
+		},
+		
+		createNumberEditor: function(config) {
+			editor = $(this.template.number);
+			editor.attr("datatype", column.datatype);
+			editor.attr("errormsg", column.errormsg);
+			editor.change(function() {
+				this.onValueChange();
+			});			
+			return editor;
+		},
+		
+		createSelect: function(config) {
+			var config = $.extend({	element: $(this.template.select) },	config);
+			var editor = new Select(config);
+			
+			if (config.dictionary) {
+				Server.getData("root/dictionary/" + config.dictionary, null, function(data) {
+					editor.loadData(data);
+				});
+			}
+			else if (config.datasource) {
+				Server.getData("root/data/procedure/" + config.datasource + "/dataset", null, function(data) {
+					editor.loadData(data);
+				});
+			}
+			else if (config.getdata) {
+				var params = null;
+				if (config.params) {
+					params = config.params;
+				}
+				Server.getData("root/data/procedure/" + config.getdata + "/dataset", params, function(data) {
+					editor.loadData(data);
+				});
+			}
+			else if (config.datas) {
+				editor.loadData(config.datas);
+			}
+			
+			return editor;
+		},
+		
+		createPopup: function(config) {
+			var editor = new PopupEditor(config);
+			return editor;
+		}
+	});
+	
+	ControlCreator = $.fm.ControlCreatorClass = new ControlCreatorClass();
+
+	
+	// ================================MonthSelector===================================//
+	DateEditor = $.fm.DateEditor = Control.subClass({
+		init: function(options) {
+			this.spliter = "-";
+			this.date = new Date(); 
+			
+			Control.call(this, options);
+			
+			this.render();
+			this.setValue();
+		},
+		
+		render: function() {
+			var me = this;
+			
+			if (this.canvas) {
+				this.canvas.change(function() {
+					if (me.onValueChange) {
+						me.onValueChange();
+					}
+				});
+			}
+		},
+		
+		getYear: function() {
+			var value = this.canvas.val();
+			
+			if (value) {
+				array = value.split(this.spliter);
+				return array && array.length > 0 ? array[0] : null;
+			}
+		},
+		
+		getMonth: function() {
+			var value = this.canvas.val();
+			
+			if (value) {
+				array = value.split(this.spliter);
+				return array && array.length > 1 ? array[1] : null;
+			}			
+		},
+		
+		appendTo: function(parent) {
+			parent.append(this.element);
+		},
+
+		getValue: function() {
+			return this.element.val();	
+		},
+		
+		setValue: function(date) {
+			if (!date) {
+				date = this.date;
+			}
+			
+			if ("string" == typeof date) {
+				var value = date.length < 10 ? date : date.substring(0,10);
+				this.element.val(value);
+			}
+			else {
+			  	var year = date.getFullYear();  
+				var month = date.getMonth() + 1;   
+				month = month < 10 ? "0" + month : month;
+			   	
+				var value = year + this.spliter + month + this.spliter + "01";
+				this.canvas.val(value);				
+			}
+		},
+		
+		setReadOnly: function(readonly, force) {
+			if (!force && (typeof this.forceReadonly != "undefined")) {
+				return;
+			}
+			
+			this.forceReadonly = force;
+			
+			if (readonly) {
+				this.element.attr("readonly", "readonly");
+			}
+			else {
+				this.element.removeAttr("readonly");
+			}
+		}
+
+	});
+	
+
+	// ================================Select===================================//
+	Select = $.fm.Select = Control.subClass({
+		init: function(options) {	
+			this.keyField = "code";
+			this.valueField = "name";
+			this.existsEmpty = true;
+			this.loaded = false;
+			
+			Control.call(this, options);
+			this.linkElement();
+			
+			if (this.data && this.onRender) {
+				this.loadData(this.data);				
+			}
+			
+			if(this.url){
+				this.getData(this.url);
+			}
+		},	
+		
+		onChangefunc: function(func) {
+			var me = this;
+			me.canvas.on("change", function() {
+				func();
+			});
+			
+		},
+		linkElement: function() {
+			var me = this;
+			
+			this.canvas.on("change", function() {
+				if (me.onValueChange) {
+					me.onValueChange();
+				}
+			});
+		},
+		
+		setURL: function(url) {
+			this.url = url;
+			this.getData(this.url);
+		},
+		
+		getData: function(url){
+			var me = this;
+			Server.getData(url, function(result){
+				me.loadData(result);
+				
+				if (me.defaultValue) {
+					me.canvas.val(me.defaultValue);
+				}
+    		});
+		},
+		
+		loadData: function(data) {
+			this.data = data;
+			this.canvas.empty();
+			
+			if (this.existsEmpty) {
+				this.canvas.append($("<option value=\"empty\" >---</option>"));
+			}
+			
+			if (data && data.length) {
+				for (var i = 0; i < data.length; i++) {
+					var line = data[i];
+					var option = $("<option></option>");
+					
+					if (this.onRender) {
+						this.onRender(line, option);
+					}
+					else {
+						option.val(line[this.keyField]);
+						option.html(line[this.valueField]);
+					}
+					
+					this.canvas.append(option);
+				}
+			}
+			
+			this.loaded = true;
+			this.setValue(this.key);
+		},
+		
+		appendTo: function(parent) {
+			parent.append(this.element);
+		},
+		
+		publishEvents: function(parent) {
+			if (this.onChange) {
+				this.registEventListener(parent, "onChange");
+			}
+		},
+		
+		onValueChange: function() {
+			var key = this.canvas.val();
+			var option = $("option:selected", this.canvas);
+			var value = option.html();
+			
+			var event = {
+				name: "onChange",
+				senderKey: this.index,
+				newValue: key,
+				record: {key: key, value: value}
+			}
+			this.fire(event);
+		},
+		
+		setValue: function(key) {
+			key = key || "empty";
+			this.key = key;
+			
+//			console.log("select[" + this.field + "], key: " + key);
+			
+			if (this.loaded) {
+//				console.log("select[" + this.field + "], setSelected");
+				
+				var option = $("option[value='" + key + "']", this.canvas);
+				option.attr("selected", "selected");
+			}
+		},
+		
+		getValue: function() {
+			var val = this.canvas.val();
+			
+			if ("empty" == val) {
+				return null;
+			}
+			
+			return val;			
+		},
+		
+		getText: function() {
+			var val = this.canvas.find("option:selected").text();
+			
+			if ("empty" == val) {
+				return null;
+			}
+			
+			return val;			
+		},
+		
+		selectByText: function(name) {
+			var option = $("option[text='" + name + "']", this.canvas);
+			option.attr("selected", "selected");
+		},
+		
+		disable: function() {
+			this.canvas.attr("disabled", "disabled");
+		},
+		
+		enable: function() {
+			this.canvas.attr("disabled", "");
+		},
+		
+		setReadOnly: function(readonly, force) {
+			if (!force && (typeof this.forceReadonly != "undefined")) {
+				return;
+			}
+			
+			this.forceReadonly = force;
+			
+			if (readonly) {
+				this.element.attr("disabled", "true");
+			}
+			else {
+				this.element.removeAttr("disabled");
+			}
+		},
+		
+		toURL: function() {
+			if (!this.fieldname) { return; }
+			
+			var value = this.canvas.val();
+			if (value) {
+				return this.fieldname + "=" + value;
+			}
+		},
+		
+		isEmpty: function() {
+			return this.canvas.val() == "empty";
+		},
+		
+		empty : function() {
+			this.canvas.val("empty");
+		}
+	});
+	
+	
+	// ================================PopupEditor===================================//
+	PopupEditor = $.fm.PopupEditor = Control.subClass({
+		template: [
+		    "<div class='popup_editor'>",
+		    	"<input id='input' type='text' class='popup_input'>",
+		    	"<div id='btn' class='popup_button'>",
+		    		"<span style='height: 100%; vertical-align: middle; display: inline-block;'></span>",
+		    		"<img src='root/image/more.png' style='width: 14px;'>",
+		    	"</div>",
+		    "</div>"     
+		],
+		
+		init: function(options) {
+			this.field = null;
+			this.readOnly = false;
+			this.isClik = false;
+			
+			Control.call(this, options);
+			
+			this.popupConfig = $.extend({
+					width: 600,
+					height: 260,
+					callback: this.doCallback,
+					callbackReciver: this
+				}, 
+				this.popupConfig
+			);
+			
+			this.createElements();
+		},
+		
+		createElements: function() {
+			var me = this;
+			this.editor = $(this.template.join(""));
+			
+			this.editor.input = $("#input", this.editor);
+			this.editor.button = $("#btn", this.editor);
+			
+			this.editor.click(function() {
+				if (!me.readOnly) {
+					me.popup();
+				}
+			});
+			
+			if (this.element) {
+				this.element.append(this.editor);
+			}
+		},
+		
+		popup: function() {
+			Win.popup(this.popupConfig);
+		},
+		
+		appendTo: function(parent) {
+			parent.append(this.editor);
+		},
+		
+		publishEvents: function(parent) {
+			if (this.onChange) {
+				this.registEventListener(parent, "onChange");
+			}
+		},
+		
+		doCallback: function(data) {
+			if (!data) {
+				return;
+			}
+			
+			if (data.record) {
+				data = data.record;
+			}
+			
+			var field = this.popupConfig || this.field;
+			var newValue = field ? data[field] : null;
+			this.onClose(newValue, data);
+		},
+		
+		onClose: function(newValue, record) {
+			var event = {
+				name: "onChange",
+				senderKey: this.index,
+				newValue: newValue,
+				record: record
+			}
+			this.fire(event);
+		},
+		
+		setValue: function(data) {
+			this.editor.input.val(data);
+		},
+		
+		getValue: function() {
+			return this.editor.input.val() == "" ? null : this.editor.input.val();
+		},
+		
+		setReadOnly: function(readonly, force) {
+			var me = this;
+			
+			if (!force && (typeof this.forceReadonly != "undefined")) {
+				return;
+			}
+			
+			this.forceReadonly = force;
+			this.readOnly = readonly;
+		}
+	});
+	
+	
+	// ================================SelectGroup===================================//
+	SelectGroup = $.fm.SelectGroup = Control.subClass({
+		init: function(options) {	
+			this.selects = [];
+			
+			Control.call(this, options);
+			this.linkSelects();
+		},	
+		
+		linkSelects: function() {
+			var me = this;
+			var els = $("select", this.element);
+			
+			for (var i = 0; i < els.length; i++) {
+				var el = $(els.get(i));
+				
+				if (this.onchange) {
+					el.on("change", function() {
+						me.onchange.call(me);
+					});
+				}
+
+				this.selects.push(el);
+			}			
+		},
+		
+		doChange: function() {
+			if (this.onchage) {
+				this.onchage();
+			}
+		},
+		
+		toURL: function() {
+			if (!this.fieldname) { return; }
+			
+			var max = this.selects.length - 1;
+			for (var i = max; i >= 0; i--) {
+				var select = this.selects[i];
+				var value = select.val();
+				
+				if (value) {
+					return this.fieldname + "=" + value;
+				}
+			}
+		},
+		
+		isEmpty: function() {
+			for (var i = 0; i < this.selects.length; i++) {
+				var select = this.selects[i];
+				var value = select.val();
+				
+				if (value) {
+					return false;
+				}
+			}
+			
+			return true;
+		}
+	});
+	
+	
+    // ================================Record===================================//
+	Record = $.fm.Record = Control.subClass ({
+		init: function(options) {
+			this.datalink = {};
+			this.labellink = {};
+			this.imglink = {};
+			this.selectlink = {};
+			this.data = {};
+			this.editClasss = ["input", "textarea"];
+			
+			Control.call(this, options);
+			
+			this.linkTo(this.canvas);
+			this.publishData();
+		},
+		
+		linkTo: function(element) {
+			if (!element) return;
+			
+			for (var no in this.editClasss) {
+				var editClass = this.editClasss[no];
+				var valueEl = $(editClass, element);
+				this.doLinkTo(valueEl, this.datalink);
+			}
+			
+			var valueEl = $("select", element);
+			this.doLinkTo(valueEl, this.selectlink);
+			
+			var valueEl = $("label", element);
+			this.doLinkTo(valueEl, this.labellink);
+
+			var valueEl = $("div", element);
+			this.doLinkTo(valueEl, this.labellink);
+			
+			var valueEl = $("img", element);
+			this.doLinkTo(valueEl, this.imglink);
+		},
+		
+		doLinkTo: function(valueEl, link) {
+			for (var i = 0; i < valueEl.length; i++) {
+				var item = $(valueEl.get(i));
+				var fieldname = item.attr("id");
+				
+				if (fieldname) {
+					fieldname = fieldname.toLowerCase();
+					link[fieldname] = item;
+				}
+			}
+			
+			this.publishData();
+		},
+		
+		setData: function(data) {
+			this.data = data;
+			this.publishData();
+		},
+		
+		setValue: function(name, value) {
+			this.data[name] = value;
+		},
+		
+		publishData: function() {
+			if (!this.data) return;
+			
+			for (var name in this.datalink) {
+				this.datalink[name].val(this.data[name]);
+			}
+			
+			for (var name in this.selectlink) {
+				var link = this.selectlink[name];
+				var value = this.data[name];
+				if (!value) { value = ""; };
+				var option = $("option[value='" + value + "']", link);
+				option.attr("selected", "selected");
+			}
+			
+			for (var name in this.labellink) {
+				var name_data = this.data[name];
+				this.labellink[name].html(this.data[name]);
+			}
+			
+			for (var name in this.labellink) {
+				var name_data = this.data[name];
+				this.labellink[name].html(this.data[name]);
+			}
+			
+			for (var name in this.imglink) {
+				this.imglink[name].attr("src", this.data[name]);
+			}
+		},
+		
+		setEditable: function(editable) {
+			for (var name in this.datalink) {
+				if (editable) {
+					this.datalink[name].removeAttr("readonly");
+				}
+				else {
+					this.datalink[name].attr("readonly", "readonly");
+				}
+			} 
+		},
+		
+		getData: function() {
+			var result = this.data || {};
+			
+			for (var name in this.datalink) {
+				var link = this.datalink[name];
+				var value = link.val();
+				
+				if (!value || value == "") { continue; };
+				result[name] = value;
+			}
+			
+			for (var name in this.selectlink) {
+				var link = this.selectlink[name];
+				var value = $("option:selected", link).val();
+				
+				if (!value || value == "") { continue; };
+				result[name] = value;
+			}
+			
+			return result;
+		},
+		
+		validate: function() {
+			for (var name in this.datalink) {
+				var link = this.datalink[name];
+				var required = link.attr("require");
+				
+				if (required) {
+					var value = link.val();
+					if (!value) {
+						Dialog.alert("璇峰~鍐欌��" + required + "鈥�");
+						return false;
+					}
+				}
+			}
+			
+			return true;
+		}
+	});
+	
+	//================================MenuBar===================================//
+	MenuBar = $.fm.MenuBar = Control.subClass({
+		template: [
+		   	'<div class="bar_item" align="center">',
+				'<img id="img" class="bar_item_img">',
+				'<div id="txt" class="bar_item_text"></div>',
+			'</div>'
+		],
+		template_left: [
+		   	'<div class="bar_item_left"></div>'
+		],
+				
+		init: function(options) {
+			var me = this;
+			this.items = new Array();
+			
+			this.defaultIndex = 0;
+			this.barClass = "bar";
+			this.bgColor = "#EFEFEF";
+			this.touchColor = "#F7B3AF";
+			this.selectColor = "#F7B3AF";
+			this.align = "left";
+			
+			Control.call(this, options);
+			
+			this.canvas.addClass(this.barClass);
+			
+			if (this.url) {
+				Server.getData(this.url, function(data) {
+					me.createItems(data);
+				});
+			}
+			else if (this.data) {
+				this.createItems(this.data);
+			}
+		},
+		
+		createItems: function(data) {
+			var me = this; 
+			
+			if (!data || data.length == 0) {
+				return;
+			}
+			
+			this.items.left =  $(this.template_left.join(""));
+			this.canvas.append(this.items.left);
+			
+			for (var i = 0; i < data.length; i++) {
+				var line = data[i];
+				
+				//1. create element
+				var item = $(this.template.join(""));
+				this.items.push(item);
+				
+				//2. get image
+				item.img = $("#img", item);
+				item.img.attr("src", line.img);
+				
+				//3. get text
+				item.text = $("#txt", item);
+				item.text.html(line.text);
+				item.text.addClass(this.unselectClass);
+				item.css({"background-color": this.bgColor});
+				
+				//4. set data
+				item.data('el', item);
+				item.data('record', line);
+				
+				//5. event
+				item.click(function(e) {
+					var sender = $(this);
+					var el = sender.data('el');
+					me.selectItem(el);
+				});
+				
+				item.on("touchstart", function() {
+					var el = $(this); 
+					el.css("background-color", this.touchColor);
+				});
+				
+				item.on("touchend", function() {
+					var el = $(this);
+					var record = el.data("record");
+					el.css("background-color", record.bgColor);
+				});
+				
+				//6. add to canvas
+				if (this.onRender) {
+					this.onRender(line, item, i);
+				}
+				
+				//7. add to canvas
+				this.canvas.append(item);
+			}
+			
+			if (this.align == "center") {
+				var margin_left = ((5 - this.items.length) * 10) + "%";
+				this.items.left.width(margin_left);
+			}
+			
+			this.selectByIndex(this.defaultIndex);
+			
+			if (this.afterLoad) {
+				this.afterLoad(this, this.items);
+			}
+		},
+		
+		selectByIndex: function(index) {
+			if (index < this.items.length) {
+				var item = this.items[index];
+				this.selectItem(item);
+			}			
+		},
+		
+		selectItem: function(item) {
+			if (this.selected) {
+				this.selected.css("background-color", this.bgColor);
+			}
+			
+			this.selected = item;
+			this.selected.css("background-color", this.selectColor);
+			
+			if (this.onSelect) {
+				var record = item.data('record');
+				this.onSelect.call(this, record, item);	
+			}
+		},
+		
+		getItemById: function(id) {
+			for (var i = 0; i < this.items.length; i++) {
+				var item = this.items[i];
+				var record = item.data('record');
+				
+				if (record && record.id == id) {
+					return item;
+				} 
+			}
+		},
+		
+		onWinShow: function(id) {
+			var item = this.getItemById(id);
+			
+			if (item) {
+				this.selectItem(item);
+			}
+		}
+	});
+	
+	
+	//================================ListMenu===================================//
+	ListMenu = $.fm.ListMenu = Control.subClass({
+		template: [
+		    '<div align="center" class="listmenu_item">',
+				'<div style="width: 185px; height: 40px; margin-top: 15px;">',
+					'<div style="float: left; width: 30px">',
+						'<img id="image" style="width: 30px; height: 30px">',
+					'</div>',
+					'<div id="text" class="listmenu_item_text"></div>',
+				'</div>',
+			'</div>'
+		],
+	
+		init: function(options) {
+			options = options ? options : {};
+			Control.call(this, options);
+			
+			if (this.url) {
+				var me = this;
+				Server.getData(this.url, function(data) {
+					me.items = data;
+					this.createItems();
+				});
+			}
+			else {
+				this.createItems();
+			}
+		},
+		
+		createItems: function() {
+			var me = this, items = this.items;
+			
+			if (!items || items.length == 0) {
+				return;
+			}
+			
+			if (!this.canvas) {
+				return;
+			}
+			
+			for (var i = 0; i < items.length; i++) {
+				var itemData = items[i];
+				var item = $(this.template.join(""));
+				
+				item.data('el', item);
+				item.data('data', itemData);
+				
+				item.text = $("#text", item);
+				item.image = $("#image", item);
+				
+				item.text.html(itemData.text);
+				item.image.attr("src", itemData.imageurl);				
+				
+				item.click(function(e) {
+					var el = $(this).data('el');
+					var data = $(this).data('data');
+					me.onItemSelected.call(me, el, data);
+				});
+				
+				this.canvas.append(item);
+			}
+		},
+		
+		onItemSelected: function(el, data) {
+			if (data && data.url) {
+				window.location.href = data.url;
+			}
+		}
+	});
+	
+	GroupMenu = $.fm.GroupMenu = Control.subClass({
+		template: [
+		   	'<div id="gm_group" class="gm_group">',
+		   		'<div class="gm_header" id="gm_header">',
+		   			'<div id="indicator" class="gm_header_indicator"></div>',
+		   			'<img id="gm_header_img" class="gm_header_img"/>',
+		   			'<div id="gm_header_text" class="gm_header_text"></div>',
+		   		'</div>',
+			'</div>'
+		],
+		
+		template_item: [
+			'<div class="gm_menu" id="gm_menu">',
+				'<img id="gm_menu_img" class="gm_menu_img"/>',
+				'<div id="gm_menu_text" class="gm_menu_text"></div>',
+			'</div>',
+		],
+	
+		init: function(options) {
+			var me = this;
+			this.mutex = true;    		//menu闂村睍寮�鐩告枼锛岄粯璁ょ浉鏂�
+			this.activeMenuIdx = 0;    	//榛樿閫変腑绗竴涓猰enu鐨勭涓�涓猧tem
+			this.activeGroupIdx = 0;    	//榛樿绗簩涓猰enu涓哄紑鍚姸鎬�
+			this.groups = [];
+			this.groupMap = {};
+			this.selectedGroup = null;
+			this.selectedMenu = null;
+			this.color = {
+	            indicator: "#8DC7E6",
+	            header: "#2A58AD",
+	            headerFont: "white",
+	            headerSelected: "#1D4B9E",
+	            headerSelectedFont: "white",
+	            headerHover: "#23a9f0",
+	            headerHoverFont: "white",
+	            menu: "#2A58AD",
+	            menuFont: "white",
+	            menuSelected: "#1D4B9E",
+	            menuSelectedFont: "white",
+	            menuHover: "#23a9f0",
+	            menuHoverFont: "white"
+	        };
+			
+			Control.call(this, options);
+
+			this.canvas.css("background", this.color.background);
+			
+			if (this.url) {
+				Server.getData(this.url, function(data) {
+					me.createElements(data);
+				});
+			}
+			else if (this.data) {
+				this.createElements(this.data);
+			}
+		},
+		
+		setURL: function(url) {
+			var me = this;	this.url = url;
+			
+			Server.getData(this.url, function(data) {
+				me.createElements(data);
+			});			
+		},
+		
+		clear: function() {
+			this.groups = [];
+			this.groupMap = new Object();
+			this.selectedGroup = null;
+			this.selectedMenu = null;
+			this.canvas.empty();
+		},
+		
+		queryType: function(record) {
+			if (record.text == "-") {
+				return "spliter";
+			}
+			
+			if (!record.parentid) {
+				return "group";
+			}
+			
+			return "menu";
+		},
+		
+		createElements: function(data) {
+			this.clear();
+			if (!data || data.length == 0) {
+				return;
+			}
+			
+			//1. create all groups
+			for (var i = 0; i < data.length; i++) {
+				var line = data[i];
+				var type = this.queryType(line);
+				
+				if ("group" == type) {
+					this.createOneGroup(line);
+				}
+			}
+
+			//2. create all menus
+			for (var i = 0; i < data.length; i++) {
+				var line = data[i];
+				var type = this.queryType(line);
+				
+				if ("menu" == type) {
+					this.createOneMenu(line);
+				}
+			}
+			
+			//3. set default active
+			this.selectByIndex(this.activeGroupIdx, this.activeMenuIdx);
+		},
+		
+		createOneGroup: function(line) {
+			var me = this;
+			
+			var group = $(this.template.join(""));
+			var header = group.header = $("#gm_header", group);
+			group.menus = [];
+			group.record = line;
+			group.active = false;
+			
+			header.indicator = $("#indicator", header);
+			header.image = $("#gm_header_img", header);
+			header.text = $("#gm_header_text", header);
+			
+			header.image.attr("src", line.img);
+			header.text.html(line.text);
+			this.setHeaderColor(header, header.indicator, "");
+			
+			header.click(function() {
+				me.selectGroup(group, true);
+			});
+			
+			header.hover(
+				function() {
+					me.setHeaderColor(header, header.indicator, "hover");
+    			},
+    			function() {
+    				var status = (me.selectedGroup == group) ? "selected" : "";
+    				me.setHeaderColor(header, header.indicator, status);
+    			}
+    		);
+			
+			this.groups.push(group);
+			this.groupMap[line.id] = group;
+			this.canvas.append(group);
+		},
+		
+		createOneMenu: function(line) {
+			var me = this;
+			
+			var group = this.groupMap[line.parentid];
+			if (group == null) {
+				return;
+			}
+			line.parent = group.record;
+			
+			var menu = $(this.template_item.join(""));
+			menu.record = line;
+			
+			menu.image = $("#gm_menu_img", menu);
+			menu.text = $("#gm_menu_text", menu);
+			
+			menu.image.attr("src", line.img);
+			menu.text.html(line.text);
+			this.setMenuColor(menu, "");
+			
+			menu.click(function() {
+				me.selectMenu(menu);
+			});
+			
+			menu.hover(
+    			function() {
+    				me.setMenuColor($(this), "hover");
+    			},
+    			function() {
+    				var status = (me.selectedMenu == menu) ? "selected" : "";
+    				me.setMenuColor($(this), status);
+    			}
+    		);
+			
+			menu.group = group;
+			group.menus.push(menu);
+			group.append(menu);
+		},
+		
+		selectGroup: function(group) { // 閫夋嫨涓�绾ц彍鍗�  涓嶅繀椤婚�変腑浜岀骇鑿滃崟
+			if (!group || group.active) {
+				return;
+			}
+			
+			//1. change selected group
+			if (this.selectedGroup != group) {
+				if (this.selectedGroup) {
+					var old = this.selectedGroup;
+					this.setHeaderColor(old.header, old.header.indicator, "");
+				}
+				
+				this.selectedGroup = group;
+				this.setHeaderColor(group.header, group.header.indicator, "selected");
+				group.header.nextAll().slideDown("fast");
+				group.active = true;
+			}
+			
+			//2. unselected menu
+			if (!group.menus) {
+				if (this.selectedMenu) {
+					this.setMenuColor(this.selectedMenu, "");
+				}
+			}
+			
+			//3. close other group
+			if (this.mutex) {
+				for (var i = 0; i < this.groups.length; i++) {
+					var temp = this.groups[i];
+					
+					if (temp.active && temp != group && temp.menus) {
+						temp.header.nextAll().slideUp("fast");
+						temp.active = false;
+					}
+				}
+			}			
+			
+			//4. invoke selected event
+			if (this.onSelected) {
+				this.onSelected.call(this, group.record);
+			}
+		},
+		
+		selectMenu: function(menu) { // 閫夋嫨浜岀骇鑿滃崟  蹇呴』閫変腑瀵瑰簲鐨勪竴绾ц彍鍗�
+			//1.
+			if (this.selectedMenu != menu) {
+				if (this.selectedMenu) {
+					this.setMenuColor(this.selectedMenu, "");
+				}
+				
+				this.selectedMenu = menu;
+				this.setMenuColor(menu, "selected");
+			}
+			
+			//2.
+			this.selectGroup(menu.group);
+			
+			//3.
+			if (this.onSelected) {
+				this.onSelected.call(this, menu.record);	
+			}
+		},
+		
+		selectByIndex: function(groupidx, menuidx) {
+			var group = this.groups[groupidx];
+			
+			if (group && group.menus && group.menus[menuidx]) {
+				this.selectMenu(group.menus[menuidx]);
+				return;
+			}
+			
+			this.selectGroup(group);
+		},
+		
+		setHeaderColor: function(header, indicator, status) {
+			var color = this.color;
+			
+			if ("hover" == status) {
+				indicator.css("background", "");
+				header.css({"background": color.headerHover, "color": color.headerHoverFont});
+			}
+			else if ("selected" == status) {
+				indicator.css("background", color.indicator);
+				header.css({"background": color.headerSelected, "color": color.headerSelectedFont});
+			}
+			else {
+				indicator.css("background", "");
+				header.css({"background": color.header, "color": color.headerFont});
+			}
+		},
+		
+		setMenuColor: function(menu, status) {
+			var color = this.color;
+			
+			if ("hover" == status) {
+				menu.css({"background": color.menuHover, "color": color.menuHoverFont});
+			}
+			else if ("selected" == status) {
+				menu.css({"background": color.menuSelected, "color": color.menuSelectedFont});
+			}
+			else {
+				menu.css({"background": color.menu, "color": color.menuFont});
+			}
+		}
+	});
+	
+
+	//================================LeftMenu===================================//
+	LeftMenu = $.fm.LeftMenu = Control.subClass({
+		template: [
+		   	'<div class="menu">',
+		   		'<div id="indicator" class="menu_indicator"></div>',
+				'<div class="menu_img">',
+					'<img id="image" style="width: 28px">',
+				'</div>',
+				'<div id="text" class="menu_txt">',
+				'</div>',
+			'</div>'
+		],
+		template_seperator: [
+     		'<div class="menu-seperator">',
+			'</div>'
+		],
+	
+		init: function(options) {
+			var me = this;
+			this.items = [];
+			this.defaultIndex = 0;
+			this.selectClass = "menu_select";
+			this.unselectClass = "menu_unselect";
+			this.indicatorSelectClass = "menu_indicator_select";
+			
+			Control.call(this, options);
+			
+			if (this.url) {
+				Server.getData(this.url, function(data) {
+					me.createItems(data);
+				});
+			}
+			else if (this.data) {
+				this.createItems(this.data);
+			}
+		},
+		
+		setURL: function(url) {
+			var me = this;	this.url = url;
+			
+			Server.getData(this.url, function(data) {
+				me.createItems(data);
+			});			
+		},
+		
+		createItems: function(data) {
+			var me = this;
+			
+			if (!data || data.length == 0) {
+				return;
+			}
+			
+			for (var i = 0; i < data.length; i++) {
+				var line = data[i];
+				
+				if (line.text == "-") {
+					this.canvas.append($(this.template_seperator.join("")));
+					continue;
+				}
+				
+				var item = $(this.template.join(""));
+				this.items.push(item);
+				
+				item.data('el', item);
+				item.data('record', line);
+				
+				item.indicator = $("#indicator", item);
+				item.text = $("#text", item);
+				item.image = $("#image", item);
+				
+				item.text.html(line.text);
+				item.image.attr("src", line.img);				
+				
+				item.click(function(e) {
+					if (me.beforeClick) {
+						me.beforeClick.call(me);
+					}
+					var el = $(this).data('el');
+					me.selectItem(el);
+				});
+				
+				this.canvas.append(item);
+			}
+			
+			this.selectByIndex(this.defaultIndex);
+		},
+
+		selectByIndex: function(index) {
+			if (index < this.items.length) {
+				var item = this.items[index];
+				this.selectItem(item);
+			}			
+		},
+		
+		selectItem: function(item) {
+			if (this.selected) {
+				this.selected.removeClass(this.selectClass);
+				this.selected.addClass(this.unselectClass);
+				this.selected.indicator.removeClass(this.indicatorSelectClass);
+			}
+			
+			item.removeClass(this.unselectClass);
+			item.addClass(this.selectClass);
+			item.indicator.addClass(this.indicatorSelectClass);
+			
+			this.selected = item;
+			
+			if (this.onSelected) {
+				var record = item.data('record');
+				this.onSelected.call(this, record, item);	
+			}
+		},
+		
+		clear: function() {
+			this.items = [];
+			this.selected = null;
+			this.canvas.empty();
+		}
+	});
+	
+	
+	//================================Menu===================================//
+	Menu = $.fm.Menu = Control.subClass({
+		template: [
+		   	'<div class="menu_item">',
+				'<img id="img" class="menu_item_img">',
+				'<div id="txt" class="menu_item_text"></div>',
+				'<div class="menu_item_spliter"></div>',
+			'</div>'
+		],
+	
+		init: function(options) {
+			var me = this;
+			this.items = [];
+			
+			this.defaultIndex = 0;
+			this.barClass = "menu";
+			this.bgColor = "#EFEFEF";
+			this.touchColor = "#F7B3AF";
+			this.selectColor = "#F7B3AF";
+			
+			Control.call(this, options);
+			
+			this.canvas.addClass(this.barClass);
+			this.canvas.attr("align", "center");
+			this.canvas.attr("left", -101);
+			this.canvas.width(100);
+			this.closed = true;
+			
+			if (this.url) {
+				Server.getData(this.url, function(data) {
+					me.createItems(data);
+				});
+			}
+			else if (this.data) {
+				this.createItems(this.data);
+			}
+		},
+		
+		setURL: function(url) {
+			this.url = url; var me = this;
+			Server.getData(this.url, function(data) {
+				me.createItems(data);
+			});			
+		},
+		
+		createItems: function(data) {
+			var me = this;
+			
+			this.clear();
+			
+			if (!data || data.length == 0) {
+				return;
+			}
+			
+			for (var i = 0; i < data.length; i++) {
+				var line = data[i];
+				
+				//1. create element
+				var item = $(this.template.join(""));
+				this.items.push(item);
+				
+				//2. get image
+				item.img = $("#img", item);
+				item.img.attr("src", line.img);
+				
+				//3. get text
+				item.text = $("#txt", item);
+				item.text.html(line.text);
+				item.text.addClass(this.unselectClass);
+				item.css({"background-color": this.bgColor});
+				
+				//4. set data
+				item.data('el', item);
+				item.data('record', line);
+				
+				//5. event
+				item.click(function(e) {
+					var sender = $(this);
+					var el = sender.data('el');
+					me.selectItem(el);
+				});
+				
+				item.on("touchstart", function() {
+					var el = $(this); 
+					el.css("background-color", this.touchColor);
+				});
+				
+				item.on("touchend", function() {
+					var el = $(this);
+					var record = el.data("record");
+					el.css("background-color", record.bgColor);
+				});
+				
+				//6. add to canvas
+				if (this.onRender) {
+					this.onRender(line, item, i);
+				}
+				
+				//7. add to canvas
+				this.canvas.append(item);
+			}
+			
+			this.selectByIndex(this.defaultIndex);
+			
+			if (this.afterLoad) {
+				this.afterLoad(this, this.items);
+			}
+		},
+		
+		clear: function() {
+			this.selected = null;
+			this.items = [];
+			this.canvas.empty();
+		},
+		
+		selectByIndex: function(index) {
+			if (index < this.items.length) {
+				var item = this.items[index];
+				this.selectItem(item);
+			}			
+		},
+		
+		selectItem: function(item) {
+			if (this.selected) {
+				this.selected.css("background-color", this.bgColor);
+			}
+			
+			this.close();
+			this.selected = item;
+			this.selected.css("background-color", this.selectColor);
+			
+			if (this.onSelect) {
+				var record = item.data('record');
+				this.onSelect.call(this, record, item);	
+			}
+		},
+		
+		open: function() {
+			if (!this.closed) {
+				return;
+			} 
+			
+			this.closed = false;
+			this.canvas.animate({left:0, width: 100}, 200);
+		},
+		
+		close: function() {
+			if (this.closed) {
+				return;
+			} 
+			
+			this.closed = true;
+			this.canvas.animate({left: -101, width: 100}, 200);
+		},
+		
+		toggle: function(e) {
+			if (this.closed) {
+				this.open();
+			}
+			else {
+				this.close();
+			}
+			
+			if (e) {
+				e.stopPropagation();
+			}
+		}
+	});	
+
+
+	//================================PopupMenu===================================//
+	PopupMenu = $.fm.PopupMenu = Control.subClass({
+		template: [
+		   	'<div class="l-menu" style="width: 140px; display: none;" ligeruiid="Menu1000">',
+				'<div class="l-menu-yline"></div>',
+				'<div class="l-menu-over" style="top: -24px;">',
+					'<div class="l-menu-over-l"></div>',
+					'<div class="l-menu-over-r"></div>',
+				'</div>',
+				'<div id="menu-body" class="l-menu-inner">',
+				'</div>',
+			'</div>'
+		],
+		template_item: [
+            '<div class="l-menu-item">',
+				'<div id="img" class="l-menu-item-icon"></div>',
+				'<div id="txt" class="l-menu-item-text"></div>',
+			'</div>',
+		],
+		template_line: [
+		    '<div class="l-menu-item-line"></div>'
+		],
+			
+		init: function(options) {
+			this.items = [];
+			Control.call(this, options);
+			
+			this.createElement();
+			this.createItems();
+		},
+	
+		createElement: function() {
+			var me = this;
+			
+			this.element = $(this.template.join(""));
+			this.body = $("#menu-body", this.element);
+			this.canvas.append(this.element);
+			
+			var item_new = $("#item_new", this.element);
+			item_new.click(function() {
+				me.element.hide();
+				Win.popup("root/page/work/bidding.html");
+			});
+			
+			var item_delete = $("#item_delete", this.element);
+			item_delete.click(function() {
+				me.element.hide();
+				Dialog.confirm("鍒犻櫎", "鏄惁鍒犻櫎褰撳墠鍗曞厓鏍煎唴瀹�?", function() {
+					
+				});
+			});
+		},
+		
+		createItems: function() {
+			if (this.items) {
+				for (var i = 0; i < this.items.length; i++) {
+					this.createOneItem(this.items[i]);
+				}
+			}
+		},
+		
+		createOneItem: function(item) {
+			var me = this;
+			
+			if (item.text == "-") {
+				this.body.append($(this.template_line.join("")));
+				return;
+			}
+			
+			var el = item.el = $(this.template_item.join(""));
+			
+			//1. 
+			if (item.disable) {
+				el.addClass("l-menu-item-disable");
+			}
+			
+			//2. get image
+			el.img = $("#img", el);
+			
+			//3. get text
+			el.text = $("#txt", el);
+			el.text.html(item.text);
+			
+			//4. set data
+			el.data('el', el);
+			el.data('item', item);
+			
+			//5. event
+			el.click(function(e) {
+				me.hide();
+				
+				var sender = $(this);
+				var el = sender.data('el');
+				var item = sender.data('item');
+				
+				if (item.onClick && !item.disable) {
+					item.onClick(el, item);
+				}
+			});
+			
+			//6.
+			this.body.append(el);
+		},
+		
+		show: function(left, top) {
+			if (left && top) {
+				this.element.css({
+					"left": left,
+					"top": top
+				});
+			}
+			
+			this.element.show();
+		},
+		
+		hide: function() {
+			this.element.hide();
+		},
+		
+		setDisable: function() {
+			var disable = {};
+			for (var i = 0; i < arguments.length; i++) {
+				disable[arguments[i]] = true;
+			}
+			
+			for (var i = 0; i < this.items.length; i++) {
+				var item = this.items[i];
+				
+				if (!item.el) {
+					continue;	
+				}
+				
+				if (disable[item.id]) {
+					item.disable = true;
+					item.el.addClass("l-menu-item-disable");
+				}
+				else {
+					item.disable = false;
+					item.el.removeClass("l-menu-item-disable");
+				}
+			}
+		}
+		
+	});	
+	
+	//================================Tab===================================//
+	Tab = $.fm.Tab = Control.subClass({
+		init: function(options) {
+			this.items = [];
+			this.headers = [];
+			this.defaultIndex = 0;
+			
+			Control.call(this, options);
+			
+			this.collectPages();
+			this.collectHeaders();
+		},
+		
+		collectPages: function() {
+			for (var i = 0; i < this.pages.length; i++) {
+				var page = this.pages[i];
+				
+				if ("string" == $.type(page)) {
+					if (page.charAt(0) != "#") {
+						page = "#" + page;
+					}
+					
+					this.pages[i] = $(page);
+				}
+			}
+		},
+		
+		collectHeaders: function() {
+			var me = this;
+
+			for (var i = 0; i < this.headers.length; i++) {
+				var header = this.headers[i];
+				
+				if ("string" == $.type(header)) {
+					if (header.charAt(0) != "#") {
+						header = "#" + header;
+					}
+					
+					this.items.push($(header));
+				}
+			}
+			
+			var width = this.headerWidth || Math.floor(100 / this.headers.length) + "%";
+			
+			for (var i = 0; i < this.items.length; i++) {
+				var item = this.items[i];
+				item.attr("class", "div_tab_off");
+				item.index = i;
+				item.width(width);
+				if (this.headerHeight) {
+					item.height(this.headerHeight);
+					item.css({"line-height": this.headerHeight + "px"});
+				}
+				item.data("el", item);
+				
+				item.click(function() {
+					var el = $(this).data("el"); 
+					me.select(el);
+				});
+			}
+			
+			if ((me.defaultIndex >= 0) && (me.defaultIndex < me.items.length)) {
+				me.select(me.defaultIndex);
+			}
+		},
+		
+		select: function(item) {
+			if ($.isNumeric(item)) {
+				item = this.items[item];
+			}
+			
+			//1.
+			if (this.selected) {
+				if (this.pages && this.pages[this.selected.index]) {
+					this.pages[this.selected.index].hide();
+				}
+				
+				this.selected.attr("class", "div_tab_off");
+			}
+			
+			//2.
+			this.selected = item;
+			
+			if (this.pages && this.pages[item.index]) {
+				this.pages[item.index].show();
+			}
+			
+			item.attr("class", "div_tab_on");
+			
+			//3.
+			if (this.onSelect) {
+				var id = item.attr("id");
+				this.onSelect(id, this);
+			} 
+		}
+	});
+	
+	//================================Options===================================//
+	Options = $.fm.Options = Control.subClass({
+		init: function(options) {
+			this.items = [];
+			this.defaultIndex = 0;
+			
+			Control.call(this, options);
+			
+			this.canvas.attr("class", "options");
+			this.canvas.attr("align", "center");
+			this.renderItems();
+		},
+		
+		renderItems: function() {
+			var me = this, items = $("button", this.canvas);
+			
+			for (var i = 0; i < items.length; i++) {
+				//1. create item
+				var item = $(items.get(i));
+				
+				if (i == 0) {
+					item.attr("class", "options_off options_left");
+				}
+				else if (i == items.length - 1) {
+					item.attr("class", "options_off options_right");
+				}
+				else {
+					item.attr("class", "options_off");
+				}
+				
+				item.data("el", item);
+				this.items.push(item);
+				
+				//2. event
+				item.click(function() {
+					var el = $(this).data("el"); 
+					me.select(el);
+				});
+			}
+			
+			if (me.defaultIndex < me.items.length) {
+				me.select(me.defaultIndex);
+			}
+		},
+		
+		select: function(item) {
+			if ($.isNumeric(item)) {
+				item = this.items[item];
+			}
+			
+			if (this.selected) {
+				this.selected.removeClass("options_on");
+				this.selected.addClass("options_off");
+			}
+			
+			this.selected = item;
+			this.selected.removeClass("options_off");
+			this.selected.addClass("options_on");
+			
+			if (this.onSelect) {
+				this.onSelect(item, this);
+			}
+		},
+		
+		val: function() {
+			if (this.selected) {
+				return this.selected.attr("id");
+			}
+		},
+		
+		toURL: function() {
+			if (this.fieldname) {
+				if (this.selected) {
+					return this.fieldname + "=" + this.selected.attr("id");
+				}
+			}
+		}
+	});
+	
+	//================================List===================================//
+	List = $.fm.List = Control.subClass({
+		init: function(options) {
+			var me = this;
+			me.items = [];
+			me.lazyLoad = false;
+			Control.call(this, options);
+			
+			if (me.url && !me.lazyLoad) {
+				Server.getData(this.url, function(data) {
+					me.createItems(data);
+				});
+			}
+			else if (me.data) {
+				me.createItems(me.data);
+			}			
+		},
+		
+		setData: function(data) {
+			if (data) {
+				this.clear();
+				this.createItems(data);
+			}
+		},
+		
+		setURL: function(url) {
+			var me = this;
+			this.url = url;
+			this.clear();
+			Server.getData(this.url, function(data) {
+				me.createItems(data);
+			});			
+		},
+		
+		createItems: function(data) {
+			if (!data) { return; }
+			
+			for (var i = 0; i < data.length; i++) {
+				var item = this.createOneItem(data[i], 0);
+				this.canvas.append(item);
+			}
+			
+			this.select(this.defaultIndex);
+		},
+		
+		appendItems: function(currentItem, data) {
+			if (!data) { return; }
+			currentItem = currentItem || this.items[this.items.length - 1];
+			
+			for (var i = 0; i < data.length; i++) {
+				var item = this.createOneItem(data[i]);
+				currentItem.after(item);
+				currentItem = item;
+			}
+		},
+		
+		appendSubItems: function(currentItem, data) {
+			if (!data) { return; }
+			currentItem = currentItem || this.items[this.items.length - 1];
+			
+			for (var i = 0; i < data.length; i++) {
+				var item = this.createOneItem(data[i]);
+				currentItem.append(item);
+			}
+		},
+		
+		createOneItem: function(line, level) {
+			var me = this; 
+			
+			var item = $(me.template.join(""));
+			item.record = line;
+			item.level = level;
+			item.data("el", item);
+			me.items.push(item);
+			
+			if (me.onRender) {
+				me.onRender(line, item, me);
+			}
+			
+			item.click(function() {
+				var el = $(this).data("el"); 
+				me.select(el);
+			});
+			
+			return item;
+		},
+		
+		select: function(item) {
+			if ($.isNumeric(item)) {
+				item = this.items[item];
+			}
+			
+			if (this.onSelect) {
+				this.onSelect(item.record, item);
+			}
+		},
+		
+		refresh: function() {
+			var me = this;
+			if (me.url) {
+				Server.getData(this.url, function(data) {
+					me.createItems(data);
+				});
+			}			
+		},
+		
+		clear: function() {
+			this.data = null;
+			this.items = [];
+			
+			if (this.empty) {
+				this.empty();
+			}
+			else {
+				this.canvas.empty();
+			}
+		},
+		
+		renderItme: function(item){
+			this.canvas.append(item);
+		}
+	});
+	
+	
+	//================================List===================================//
+	DataList = $.fm.DataList = Control.subClass({
+		headerTemplate: [
+		    '<div></div>'
+		],		
+		rowTemplate: [
+		    '<div></div>'
+		],
+		cellTemplate: [
+			'<div></div>',
+		],
+		checkTemplate: [
+		    '<div align = right class="datalist_cell" >',
+		    	'<div class="datalist_click_outer">',
+			    	'<div id="innerCheck" class="datalist_click_selected"></div>',
+				'</div>',		    
+		    '</div>'
+		],		
+		  		
+		init: function(options) {
+			options = options ? options : {};
+			
+			this.data = [];
+			this.items = [];
+			this.rows = [];
+			this.selected = null;
+			this.dblclick = false;
+			this.closeOnSelect = true;
+			this.showLineNo = true;
+			this.lineNoWidth = 10;
+			this.headerHtml = null;
+			this.headerClass = "datalist_header";
+			this.rowClass = "datalist_row";
+			this.cellClass = "datalist_cell";
+			this.evenClass = "datalist_row_interval";
+			this.evenFlag = true;
+			this.evenActive = true;
+			this.orderby = "asc";
+			this.sequence = 0;
+
+			
+			Control.call(this, options);
+			
+			this.initItems();
+			this.createHeader();
+			
+			if (this.data) {
+				this.loadData(this.data);
+			}
+		},
+		
+		initItems: function() {
+			//add line no
+			if (this.showLineNo) {
+				var items = this.items;
+				
+				this.items = new Array(items.length + 1);
+				this.items[0] = {text: "琛�", field: "lineno", width: this.lineNoWidth + "%", align: "center"};
+				
+				for (var i = 0; i < items.length; i++) {
+					this.items[i + 1] = items[i];
+				}
+			}
+		},
+		
+		createHeader: function() {
+			if (this.headerHtml) {
+				this.header = $(this.headerHtml.join(""));
+				this.canvas.append(this.header);
+				return;
+			}
+			
+			var items = this.items;
+			if (!items) {
+				return;
+			}
+			
+			this.header = $(this.headerTemplate.join(""));
+			this.header.addClass(this.headerClass);
+			
+			for (var i = 0; i < items.length; i++) {
+				var item = items[i];
+				this.createOneCell(this.header, item, "center", item.text);
+			}
+			
+			this.canvas.append(this.header);
+		},
+		
+		toggleSelect: function(row) {
+			this.setSelect(row, !row.selected);
+		},
+		
+		createBlankRow: function() {
+			var blankRow = $(this.rowTemplate.join(""));
+			this.canvas.append(blankRow);
+		},
+		
+		loadData: function(dataList, offset) {
+			if (!offset) {
+				offset = 0;
+			}
+			
+			this.clear();
+			this.data = dataList;
+			
+			if (!dataList || !this.items) {
+				return;
+			}
+			
+			this.rows = [];
+			
+			for (var i = 0; i < dataList.length; i++) {
+				var data = dataList[i];
+				
+				row = this.createOneRow(i + 1 + offset, data);
+				this.rows.push(row);
+			}
+		},
+		
+		createOneRow: function(index, data) {
+			var me = this;
+			var items = this.items;
+			
+			var row = $(this.rowTemplate.join(""));
+			row.cells = {};
+			row.index = index;
+			row.record = data;
+			row.addClass(this.rowClass);
+			data.el = row;
+			
+			if (this.isEven()) {
+				row.addClass(this.evenClass);
+			}
+			
+			row.data('el', row);
+			
+			row.bind("touchstart", function() {
+				if (me.touched) {
+					me.touched.removeClass("datalist_row_touch");
+				}
+				
+				me.touched = row;
+				row.addClass("datalist_row_touch");
+			});
+			row.bind("touchend", function() {
+				row.removeClass("datalist_row_touch");
+			});
+			
+			if (!this.dblclick) {
+				row.click(function(e) {
+					var el = $(this).data('el');
+					me.selectRow.call(me, el);
+				});
+			}
+			else {
+				row.dblclick(function(e) {
+					var el = $(this).data('el');
+					me.selectRow.call(me, el);
+				});				
+			}
+			
+			if (data) {
+				var min = 0;
+				
+				//琛屽彿
+				if (this.showLineNo) {
+					min = 1;
+					var linenoCell = this.createOneCell(row, items[0], items[0].align, index);
+					row.lineno = linenoCell;
+					row.index = index;
+				}
+				
+				//鏁版嵁
+				var text;
+				for (var i = min; i < items.length; i++) {
+					var item = items[i];
+					
+					if (item.vender) {
+						text = item.vender(data);
+					}
+					else {
+						text = data[item.field];
+					}
+					
+					var cell = this.createOneCell(row, item, item.align, text);
+					row.cells[item.field] = cell;
+				}
+			}
+			
+			if (this.orderby == "desc") {
+				this.header.after(row);
+			}
+			else {
+				this.canvas.append(row);
+			}
+			
+			return row;
+		},
+		
+		createOneCell: function(row, item, align, value) {
+			var cell = $(this.cellTemplate.join(""));
+			
+			cell.addClass(this.cellClass);
+			cell.html(value);
+			
+			var css = item.css || {};
+			css["text-align"] = align;
+			cell.css(css);
+			
+			cell.width(item.width);
+			if (item.height) {
+				cell.height(item.height);
+			}
+			
+			row.append(cell);
+			return cell;
+		},
+		
+		onRowClick: function(el, data) {},
+		onRowSelected: function(data) {},
+		onRowUnselected: function(data) {},
+		
+		selectRow: function(el) {
+			el.removeClass("datalist_row_touch");
+			
+			if (!el) {
+				return;
+			}
+
+			if (this.selected) {
+				this.selected.el.removeClass("datalist_row_selected");
+			}
+			
+			el.addClass("datalist_row_selected");
+			this.selected = el.record;
+			this.onRowSelected(this.selected);
+		},
+		
+		isEven: function() {
+			if (!this.evenActive) {
+				return false;
+			} 
+			
+			this.evenFlag = !this.evenFlag;
+			return this.evenFlag;
+		},
+		
+		append: function(data) {
+			var index = this.data.length + 1;
+			this.data.push(data);
+			var row = this.createOneRow(index, data);
+			this.rows.push(row);			
+		},
+		
+		save: function() {
+			if (!this.selected) {
+				return;
+			}
+			
+			var el = this.selected.el;
+			var data = this.selected;
+			
+			for (var prop in data) {
+				var cell = el.cells[prop];
+				if (cell) {
+					cell.html(data[prop]);
+				}
+			}
+		},
+		
+		deleteLine: function(record) {
+			if (this.isEmpty() || !record) {
+				return;
+			}
+
+			var index = record.el.index - 1;
+			var data = this.data;
+			var line, lineEl;
+			
+			for (var i = index; i < data.length - 1; i++) {
+				line = data[i + 1];
+				lineEl = line.el;
+				
+				lineEl.index = i;
+				lineEl.lineno.html(i + 1);
+				data[i] = line;
+			}
+			data.pop();				
+
+			record.el.remove();
+		},
+		
+		deleteLast: function() {
+			if (this.isEmpty()) {
+				return;
+			}
+			
+			var last = this.data[this.data.length - 1];
+			this.data.pop();
+			last.el.remove();
+		},
+		
+		isEmpty: function() {
+			return !this.data || this.data.length == 0;
+		},
+		
+		clear: function() {
+			for (var i = 0; i < this.rows.length; i++) {
+				var row = this.rows[i];
+				row.remove();
+			};
+			
+			this.data = [];
+			this.rows = [];
+			this.selected = null;
+			this.sequence = 0;
+		},
+		
+		nextSequence: function() {
+			this.sequence = this.sequence + 1;
+			return this.sequence;
+		},
+		
+		getLength: function() {
+			return this.data.length;
+		},
+		
+		exists: function(field, source) {
+			if (!field || !source || !source[field]) {
+				return false;
+			}
+			
+			var value = source[field], data = this.data;
+			
+			for (var i = 0; i < data.length; i++) {
+				if (source.el && source.el.index == (i + 1)) {
+					continue;
+				}
+				
+				var line = data[i];
+				if (line[field] == value) {
+					return true;
+				}
+			}
+			
+			return false;
+		}
+		
+	});
+	
+	
+	//================================Circle===================================//
+	Indicator = $.fm.Indicator = Control.subClass({
+		template: [
+		    '<div>',
+		       	'<div id="title" class="targetor_txt"></div>',
+		       	'<div id="targetor_indicator" class="targetor_indicator">',
+					'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 200 200" class="indicator">',
+						'<circle cx="100" cy="100" r="76" class="indicator_full"></circle>',
+						'<circle id="targetor_indicator_progress" cx="100" cy="100" r="76" class="indicator_progress" transform="rotate(-90, 100, 100)"></circle>',
+						'<text id="targetor_indicator_percent" x="100" y="100" class="indicator_percent"></text>',
+						'<text id="targetor_indicator_txt" x="100" y="130" class="indicator_text"></text>',
+					'</svg>',
+		       	'</div>',
+		       	'<div id="targetor_msg" class="targetor_msg">',
+		       		'<div id="targetor_msg_a" class="targetor_msg_a">',
+		       			'<div id="label_a" class="targetor_msg_a_txt">鎸囨爣A锛氭寚鏍囧��</div>',
+		       			'<div class="targetor_msg_bar">',
+		       				'<div id="bar_a" class="targetor_msg_innerbar"></div>',
+		       			'</div>',
+		       		'</div>',
+		       		'<div style="clear: both;"></div>',
+		       		'<div id="targetor_msg_b" class="targetor_msg_b">',
+		       			'<div id="label_b" class="targetor_msg_b_txt">鎸囨爣B锛氭寚鏍囧��</div>',
+		       			'<div class="targetor_msg_bar">',
+		       				'<div id="bar_b" class="targetor_msg_innerbar"></div>',
+		       			'</div>',
+		       		'</div>',  		
+		       	'</div>',
+		       	'<button class="targetor_btn" style="display: none">璇︾粏</button>',
+		    '</div>'
+		],
+	
+		init: function(options) {
+			this.percent = 75;
+			this.title = "鏍囬";
+			this.series = [
+				{
+					text: "鎸囨爣A",
+					length: 100
+				},
+				{
+					text: "鎸囨爣A",
+					length: 100
+				}				
+			];
+			
+			this.text = "鎸囨爣";
+			this.coefficient = (76.0 * 3.6) / 57;
+			
+			Control.call(this, options);
+			
+			this.renderItems();			
+		},
+
+		renderItems: function() {
+			var items = $(this.template.join(""));
+			
+			this.el = {};
+			
+			//1. create title
+			this.el.title = $("#title", items);
+			this.el.title.html(this.title);
+			
+			//2. create indicator
+			this.el.indicator = $("#targetor_indicator", items);
+			
+			//2.1 create indicator.progress circle
+			var circleLine = Math.round(this.percent * this.coefficient);
+			this.el.indicator.progress = $("#targetor_indicator_progress", items);
+			this.el.indicator.progress.attr("stroke-dasharray", circleLine + ", 10000");			
+			
+			//2.2 create indicator.percent number
+			this.el.indicator.percent = $("#targetor_indicator_percent", items);
+			this.el.indicator.percent.html(this.percent);
+			
+			//2.2 create indicator.text
+			this.el.indicator.text = $("#targetor_indicator_txt", items);
+			this.el.indicator.text.html(this.text);
+			
+			//3.create message
+			this.el.message = $("#targetor_msg", items);
+			
+			//3.1 create message
+			this.el.message.a = $("#targetor_msg_a", this.el.message); 
+			this.el.message.a.txt = $("#label_a", this.el.message.a);
+			this.el.message.a.txt.html(this.series[0].text);
+			this.el.message.a.bar = $("#bar_a", this.el.message.a);
+			this.el.message.a.bar.width(this.series[0].length + "%");
+			
+			this.el.message.b = $("#targetor_msg_b", this.el.message); 
+			this.el.message.b.txt = $("#label_b", this.el.message.b);
+			this.el.message.b.txt.html(this.series[1].text);
+			this.el.message.b.bar = $("#bar_b", this.el.message.b);
+			this.el.message.b.bar.width(this.series[1].length + "%");
+			
+			this.canvas.append(items);
+		},
+		
+		setData: function() {
+			if (!arguments) { return; }
+			
+			this.el.indicator.percent.text(arguments[0].text);
+			this.el.indicator.progress.attr("stroke-dasharray", Math.round(arguments[0].length * this.coefficient) + ", 10000");
+			if (arguments[0].color){
+				this.el.indicator.progress.css("stroke", arguments[0].color);
+			}
+			
+			this.el.message.a.txt.text(arguments[1].text);
+			this.el.message.a.bar.width(arguments[1].length + "%");
+			if (arguments[1].color){
+				this.el.message.a.bar.css("background-color", arguments[1].color);
+			}
+			
+			this.el.message.b.txt.text(arguments[2].text);
+			this.el.message.b.bar.width(arguments[2].length + "%");
+			if (arguments[2].color){
+				this.el.message.b.bar.css("background-color", arguments[2].color);
+			}
+		}
+	});	
+	
+	
+	ChartHelperClass = $.fm.ChartHelperClass = Object.subClass({
+		size: {
+			month: 12,
+			dmonth: 6,
+			season: 4,
+			year: 1
+		},
+		
+		getPeriodValue: function(periodtype, month) {
+			if ("year" == periodtype) {
+				return 0;
+			}
+			else if ("dmonth" == periodtype) {
+				return Math.ceil(month / 2.0);
+			}
+			else {
+				return month;
+			}
+		},
+		
+		getPeriod: function(type, month) {
+			if (!type) return [];
+			
+			type = type.toLowerCase(); month = month || 12;
+			var max = 0, result = [];
+			
+			if ("month" == type) {
+				max = month;
+			}
+			else if ("dmonth" == type) {
+				max = Math.ceil(month / 2.0);
+			}
+			else if ("season" == type) {
+				max = Math.ceil(month / 3.0);
+			}
+			
+			for (var i = 1; i <= max; i++) {
+				result.push(i); 
+			}
+			return result;
+		},
+		
+		getPeriodData: function(periodType, data, multi) {
+			if (!periodType) return {};
+			multi = multi || 1;
+			
+			result = {actual: [], target: [], achieve: [], onyear: []};
+			
+			for (var i = 0; i < data.length; i++) {
+				var line = data[i];
+				result.actual.push(line.amt_actual ? line.amt_actual / multi : 0);
+				result.target.push(line.amt_target ? line.amt_target / multi: 0);
+				result.achieve.push(line.rate_achieve ? line.rate_achieve : 0);
+				result.onyear.push(line.rate_onyear ? line.rate_onyear : 0);
+			}
+			
+			return result;
+		},
+		
+		getSeriesData: function(namefield, valuefields, array, multi) {
+			if (!namefield || !array) return {};
+			multi = multi || 1;
+			
+			var result = {categories: []}, line, name, value;
+			
+			for (var i = 0; i < valuefields.length; i++) {
+				result[valuefields[i]] = [];
+			}
+			
+			for (var i = 0; i < array.length; i++) {
+				line = array[i];
+				result.categories.push(line[namefield]);
+				
+				data = result[line[namefield]] = [];
+				
+				for (var j = 0; j < valuefields.length; j++) {
+					name = valuefields[j];
+					value = line[name];
+					
+					if (name && (name.length > 4) && (name.substring(0, 4) == "amt_")) {
+						value = value ? value / multi : 0;
+					}
+					else {
+						value = value || 0;
+					}
+					
+					result[name].push(value);
+				}
+			}
+			
+			return result;
+		},
+		
+		getSeries: function(fieldname, array, valueFields) {
+			var result = [];
+
+			for (var i = 0; i < array.length; i++) {
+				array[i].amt_actual = array[i].amt_actual/10000;
+			//	array[i].rate_achieve = array[i].rate_achieve.toFixed(2);
+				array[i].rate_achieve = parseFloat(Highcharts.numberFormat(array[i].rate_achieve,2));
+				
+				var line = array[i];
+				var item = {name: line[fieldname], data: [[]]};
+				var data = item.data[0];
+				
+				for (var j = 0; j < valueFields.length; j++) {
+					data.push(line[valueFields[j]] || 0);
+				}
+				
+				result.push(item);
+			}
+			
+			return result;
+		},
+		
+		getPeriodSeries: function(periodType, namefield, valuefield, array, multi, type) {
+			multi = multi || 1; 
+			var result = [], prior = null, item = null, value;
+
+			for (var i = 0; i < array.length; i++) {
+				var line = array[i], name = line[namefield];
+				
+				if (prior != name) {
+					item = {"name": name, data: [], "type": type || "spline"};
+					prior = name;
+					result.push(item);
+				}
+				
+				value = line[valuefield];
+				value = Math.round((value ? value / multi : 0));
+				item.data.push(value);
+			}
+			
+			return result;
+		},
+		
+		getPercent: function(namefield, valuefield, array) {
+			result = [];
+			
+			for (var i = 0; i < array.length; i++) {
+				var line = array[i];
+				result.push({name: line[namefield], y: line[valuefield] || 0});
+			}
+				
+			return result;
+		},
+		
+		getStackSeriesMax: function(series) {
+			var result = {max: 0, total: 0}, max = 0, total = 0;
+			
+			for (var no in  series) {
+				var data = series[no].data || series[no];
+				total = 0;
+				
+				for (var i = 0; i < data.length; i++) {
+					if (max < data[i]) {
+						max = data[i];
+					}
+					
+					total = total + data[i];
+				}
+				
+				if (result.max < max) {
+					result.max = max;
+				}
+				
+				if (result.total < total) {
+					result.total = total;
+				}
+			}
+			
+			return result;
+		} 
+	});
+	
+	ChartHelper = new ChartHelperClass();
+	
+	//===============================checkboxTable=========================================
+	checkboxTable = $.fm.checkboxTable = Control.subClass({
+		template: [
+		    "<table style='width: 100%;'>",
+			"</table>"
+		],		
+		template_tr:[
+			"<tr>",
+			"</tr>"
+   		],
+		template_checkbox:[
+			"<td>",
+				"<label><input style='vertical-align: -2px;' type='checkbox'/></label>",
+			"</td>"
+		],
+		
+		init: function(options) {
+			var me = this;
+			this.columnsNo = 1;//榛樿鍙湁涓�鍒�
+			this.defaultUnChecked = true;
+			Control.call(this, options);
+			
+			if (this.url) {
+				
+				this.setUrl(this.url);
+			}
+			else if (this.data) {
+				this.createItems(this.data);
+			}
+		},
+		
+		createItems: function(data) {
+			var me = this; 
+			
+			if (!data || data.length == 0) {
+				return;
+			}
+			
+			this.oneTemplate =  $(this.template.join(""));
+			
+			for (var i = 0; i < data.length; i++) {
+				var template_tr = $(this.template_tr.join(""));
+				for (var idx = 0; idx < this.columnsNo + 1; idx++) {
+					var line = data[i];
+					var template_checkbox = $(this.template_checkbox.join(""));
+					template_checkbox.input = $("input", template_checkbox);
+					template_checkbox.label = $("label", template_checkbox);
+					template_checkbox.label.append(line.name);
+					template_checkbox.input.val(line.code);
+					if (line.checked == 1 && this.defaultUnChecked) {
+						template_checkbox.input.attr("checked", "checked");
+					}
+					template_tr.append(template_checkbox);
+					if (idx == this.columnsNo) {
+						i = i-1;
+					}
+					i < data.length - 1 ? i++ : idx = this.columnsNo + 1;
+				}
+				
+				this.oneTemplate.append(template_tr);
+			}
+			this.canvas.append(this.oneTemplate);
+		},
+		
+		loadData: function(data) {
+			this.canvas.empty();
+			this.createItems(data);
+		},
+		
+		setUrl: function(url) {
+			var me = this;
+			url = encodeURI(url);
+			Server.getData(url, function(data) {
+				if (me.onGetData) {
+					data = me.onGetData(data);
+				}
+				me.loadData(data);
+			});
+		},
+		
+		getSelectedData: function() {
+			var me = this;
+			var allcheckbox = $("input[type='checkbox']", this.canvas);
+			var selectedData = "";
+			var idx = 0;
+			
+			for (var i = 0; i < allcheckbox.length; i++) {
+				var checkbox = $(allcheckbox.get(i));
+				if (checkbox.is(':checked')) {
+					idx ++;
+					if (selectedData == "") {
+						selectedData = checkbox.attr('value');
+					}
+					else {
+						selectedData += "銆�" + checkbox.attr('value');
+					}
+				}
+			}
+			
+			return selectedData;
+		}
+	});
+		
+})(jQuery);	
\ No newline at end of file
diff --git a/WebRoot/js/core.js b/WebRoot/js/core.js
new file mode 100644
index 0000000..345ba99
--- /dev/null
+++ b/WebRoot/js/core.js
@@ -0,0 +1,446 @@
+(function ($) {
+	$.fm = {
+			
+			decode: function (obj) {
+				if (!obj) {
+					return null;
+				}
+				
+	        	if ($.isArray(obj)) {
+	        		return this.decodeArray(obj);
+	        	} 
+	        	else if (typeof obj == "object") {
+	        		return this.decodeObject(obj);
+	        	}
+	        	else if (typeof obj == "string") {
+	        		try {
+	        			return decodeURIComponent(obj);
+					} catch (e) {
+						return obj;
+					}
+	           	} 
+	        	else {
+	        		return obj;
+	        	}
+			},
+			
+			decodeArray: function(data) {
+				for (var i = 0; i < data.length; i++) {
+					if (typeof data[i] == 'string') {
+						data[i] = this.decode(data[i]);
+					}
+					else {
+						data[i] = this.decodeObject(data[i]);					
+					}
+				}
+				
+				return data;
+			},
+			
+			decodeObject: function(data) {
+				for (var prop in data) {
+					if (data[prop]) {
+						data[prop] = this.decode(data[prop]);					
+					}
+				}
+				
+				return data;
+			},
+			
+			encode: function(obj) {
+	        	if ($.isArray(obj)) {
+	        		return this.encodeArray(obj);
+	        	} 
+	        	else if (typeof obj == "object") {
+	        		return this.encodeObject(obj);
+	        	} 
+	        	else if (typeof obj == "string") {
+	        		return encodeURI(obj);
+	           	} 
+	        	else if (typeof obj == "boolean") {
+	        		return String(obj);
+	        	} 
+	        	else if (typeof obj == "number") {
+	        		return String(obj);
+	         	} 
+	        	else if (typeof obj === "function") {
+	        		return "";
+	        	}
+			},
+			
+		    encodeArray: function(o) {
+		        var a = ["[", ""],
+		        
+		        len = o.length,
+		        i;
+		        for (i = 0; i < len; i += 1) {
+		            a.push(this.encode(o[i]), ',');
+		        }
+		        
+		        a[a.length - 1] = ']';
+		        return a.join("");
+		    },
+		    
+		    encodeObject: function(o) {
+		    	if (!o) {
+		    		return "null";
+		    	}
+		    	if (o.length) {
+		    		return "el";
+		    	}
+		        var a = ["{", ""];
+		        
+		        for (var i in o) {
+		            if (i == 'parent') {
+		            	continue;
+		            }
+		            a.push(this.encode(i), ":", this.encode(o[i]), ',');
+		        }
+		        
+		        a[a.length - 1] = '}';
+		        return a.join("");
+		    },
+		    
+			objectToURI: function(object) {
+				if (!object) {
+					return null;
+				}
+				
+				if (typeof object == "string") {
+					return encodeURI(object);
+				}
+				
+	    		var param = null;
+	    		for (var prop in object) {
+	    			if (object[prop]) {
+	    				if (param) {
+	    					param = param + "&" + prop + "=" + encodeURI(object[prop]);
+	    				}
+	    				else {
+	    					param = prop + "=" + encodeURI(object[prop]);
+	    				}
+	    			}
+	    		}	
+	    		
+	    		return param;
+			},
+		    
+		    formatBarcode: function(value) {
+		    	if (!value) {
+		    		return value;
+		    	}
+		    	
+		    	var pos = value.indexOf(",");
+		    	if (pos > 0) {
+		    		value = value.substring(pos + 1);
+		    	}
+		    	
+		    	return value;
+		    },
+		    
+			S4 : function(){// 楠岃瘉鐮�
+				return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+			},
+
+			guid : function(){
+				return (this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4());
+			}    
+	};
+	
+	
+    Object.init = function(options) {
+		if (prototyping) {  
+			return;
+		}
+		
+		if (options) {
+        	var name = null, value;
+        	
+        	for (name in options) {
+        		value = options[name];
+    			this[name] = value;	
+        	}
+		}
+	};
+	
+
+	Object.subClass = function(properties) {
+		if (!properties) {
+			return;
+		}
+		
+		var clazz = properties.init;
+		delete properties.init;
+		
+		if (!clazz) {
+			clazz = new Function();
+		}
+		
+		prototyping = true;
+		try {
+			var prototype = new this();
+		} 
+		finally {
+			prototyping = false;
+		}
+		
+		$.extend(prototype, properties);
+		
+		clazz.prototype = prototype;
+		clazz.subClass = arguments.callee;
+		
+		return clazz;
+	};
+	
+	
+    Control = $.fm.Control = Object.subClass({
+    	
+        init: function(options) {
+    		if (prototyping) {
+    			return;
+    		}
+    		
+			Object.init.call(this, options);
+			
+			// 鍒涘缓鐢诲竷
+    		this.createCanvas(options);
+    	},
+    	
+    	createCanvas: function(options) {
+    		if (!this.element) {
+    			this.canvas = $("body");
+    			return;
+    		}
+    		
+    		this.getEl();
+    		this.canvas = this.element;
+    	},
+    	
+    	averageTo: function(total, size) {
+    		if (size <= 0) {
+    			return null;
+    		}
+    		
+    		var result = new Array(size);
+    		var max = size - 1;
+    		var value = Math.floor(total / size);
+    		var sum = 0;
+    		
+    		for (var i = 0; i < max; i++) {
+    			result[i] = value;
+    			sum = sum + value;
+    		}
+    		
+    		result[max] = total - sum;
+    		return result;
+    	},
+    	
+		getEl: function() {
+			var element = this.element;
+			
+    		if (typeof element == "string") {
+    			if ("#" != element.substring(0, 1)) {
+    				element = "#" + element;
+    			}
+    				
+    			this.element = $(element);
+    			return;
+    		}
+		},
+		
+    });
+    
+    
+	$.fm.RootParentClass = Object.subClass({
+		init: function() {
+			this.controls = [];
+			this.win = $(window);
+			this.document = $(document);
+			this._width = this.win.width();
+			this._height = this.win.height();
+		},
+		
+		width: function() {
+			return this._width;
+		},
+		
+		height: function() {
+			return this._height;
+		},
+		
+		append: function(element) {
+			if (!this.body) {
+				this.body = $('body');
+				var me = this;
+				this.document.click(function() {
+					me.notifyAll();
+				});				
+			}
+		
+			this.body.append(element);
+		},
+		
+		register: function(control) {
+			this.controls.push(control);
+		},
+		
+		notifyAll: function() {
+			for (var i = 0 ; i < this.controls.length; i++) {
+				this.notifyOne(this.controls[i]);
+			}
+		},
+		
+		notifyOne: function(control) {
+			if (control && control.onNotify) {
+				control.onNotify.call(control, "rootClick");
+			}
+		}
+	});
+	RootParent = new $.fm.RootParentClass();
+
+	
+	var ServerClass = Object.subClass({
+		dataNames: ["line", "dataset", "entityset", "rows", "tree", "user"],
+		excludeNames: {"success": true, "error": true},
+		sysParams: {
+			timeoutPage: "root/page/system/index.html"
+		},
+		
+		ajaxRequest: function(url, param, callback, onSuccess, onFail) {
+			var me = this;
+			if (param) {
+				if ($.isFunction(param)) {
+					callback = param;
+					param = null;
+				}
+				else {
+					url = url + "?" + param;
+				}
+			}
+			
+			url = serverAddress + url;
+			
+			try {
+				$.ajax(url, {
+					dataType: 'json',
+					success: function(result) {
+						if (result) {
+							if ("timeout" == result.errorcode) {
+								window.top.location.href = me.sysParams.timeoutPage;
+							}
+							else if (!result.success) {
+								if (onFail) { 
+									onFail(callback, result); 
+								}
+								else {
+									var error = result.errorcode + ": " + $.fm.decode(result.errormessage);
+									try {
+										if (console.log) {
+											console.log(error);
+										}						
+									}
+									catch (e) {	}
+									alert(error);									
+								}
+							}
+						}
+						
+						onSuccess(callback, result);
+					},
+					error: function(d1, error, message) {
+						alert(error);
+						try {
+							if (console.log) {
+								console.log(error);
+							}						
+						}
+						catch (e) {	}
+					}
+				});				
+			}
+			catch(e) {
+			}
+		},
+		
+		getResultData: function(result) {
+			if (!result) return;
+			
+			// 1.
+			for (var i = 0; i < this.dataNames.length; i++) {
+				var name = this.dataNames[i];
+				
+				if (result[name]) {
+					var data = result[name];
+					var page = result['page'];
+					return [$.fm.decode(data), $.fm.decode(page), "byPage"];
+				}
+			}
+			
+			// 2.
+			var names = [];
+			for (var prop in result) {
+				if (!this.excludeNames[prop]) {
+					names.push(prop);
+				}
+			}
+			
+			if (names.length == 1) {
+				var data = result[names[0]];
+				return $.fm.decode(data);
+			}
+		},
+		
+		call: function(url, param, callback) {
+			if (!url) {return;} var me = this;
+			
+			var afterRequest = function(doCallback, result) {
+				if (doCallback) {
+					try {
+						result = $.fm.decode(result);
+					}
+					finally {
+						doCallback(result);
+					}
+				}
+			};
+			
+			me.ajaxRequest(url, param, callback, afterRequest, afterRequest);
+		},
+		 
+		upload: function(url, file, onProgress, onSuccess, onError) {
+			var formdata = new FormData();
+			formdata.append("fileList", file);
+			try {
+				$.ajax({
+	                cache: true,
+	                type: "POST",
+					url: serverAddress + url,
+	                data: formdata,
+	                dataType: "json",
+					processData: false,
+        			contentType: false,
+					xhr: function(){
+						var xhr = $.ajaxSettings.xhr();
+						if (onProgress && xhr.upload) {
+							xhr.upload.addEventListener("progress" , onProgress, false);
+							return xhr;
+						}
+					},
+	                error: function(request) {
+	                	if (onError) { onError(); }
+	                },
+	                success: function(data) {
+	                	data = $.fm.decode(data);
+	                	if (onSuccess) { onSuccess(data); }
+	                }
+	            });
+			}
+			catch(e) {
+				if (onError) { onError(); }
+			}			
+		}
+	});
+	Server = $.fm.Server = new ServerClass();
+    
+	
+})(jQuery);
\ No newline at end of file
diff --git a/WebRoot/js/dialog.js b/WebRoot/js/dialog.js
new file mode 100644
index 0000000..731a826
--- /dev/null
+++ b/WebRoot/js/dialog.js
@@ -0,0 +1,157 @@
+	// ================================Dialog===================================//
+	Dialog = {};
+		
+	$.fm.DialogClass = Control.subClass({
+		template: [
+		     '<div class="win_mask"></div>',
+		     '<div class="dialog_mask" style="display: none; z-index: 1001;" align="center">',
+		     '<div class="dialog">',
+		    	'<div class="dialog_header" id="title">',
+		    		'淇℃伅鎻愮ず',
+		    	'</div>',
+		    	'<div class="dialog_body" id="dialog_body">',
+		    		'<div class="dialog_content" id="dialog_content">',
+		    			'<div class="dialog_image" id="image"></div>',
+		    			'<span id="body_title"></span>',
+		    			'<div class="dialog_text" id="text"></div>',
+		    		'</div>',
+		    	'</div>',
+		    	'<div class="dialog_footer" id="dialog_footer">',
+		    		'<button class="button btn_light" id="btn_cancel">鍙栨秷</button>',
+		    		'<button class="button btn_blue" id="btn_ok" style="margin-left:8px">纭畾</button>',
+		    	'</div>',			
+		    '</div>',
+		    '</div>'
+		],
+	
+		init: function(options) {
+			options = options ? options : {};
+			Control.call(this, options);
+			
+			this.createEl();
+		},
+		
+		createEl: function() {
+			var me = this;
+			var el = this.el = $(this.template.join(""));
+			
+			this.title = $("#title", el);
+			this.body = $("#dialog_body", el);
+			this.body_title = $("#body_title", el);
+			this.dialog_content = $("#dialog_content", el);
+			this.dialog_footer = $("#dialog_footer", el);
+			
+			this.image = $("#image", el);
+			this.text = $("#text", el);
+			this.btn_cancel = $("#btn_cancel", el);
+			this.btn_ok = $("#btn_ok", el);
+			
+			this.btn_cancel.click(function() {
+				me.el.hide();
+				if (me.callback) {
+					me.callback(false);
+				}
+			});
+			
+			this.btn_ok.click(function() {
+				me.el.hide();
+				if (me.callback) {
+					me.callback(true);
+				}
+			});
+			
+			this.canvas.append(this.el);
+		},
+		
+		databox: function(title, callback, config) {
+			var input = config.input || "";
+			var body_title = config.body_title || "";
+			
+			if (config.onShow) {
+				onShow();
+			}
+			
+			this.title.html(title);
+			this.body.removeAttr("class");
+			this.dialog_content.removeAttr("class");
+			this.image.removeAttr("class");
+			this.text.removeAttr("class");
+			this.dialog_footer.removeAttr("class");
+			this.body.addClass("databox_body");
+			this.dialog_content.addClass("databox_content");
+			this.image.addClass("databox_image");
+			this.text.addClass("databox_text");
+			this.dialog_footer.addClass("databox_footer");
+			
+			this.body_title.html(body_title);
+			this.text.html(input);
+			this.btn_cancel.show();			
+			
+			this.callback = callback;
+			
+			this.el.show();
+		},
+		
+		confirm: function (title, text, callback) {
+			this.title.html(title);
+			this.text.html(text);
+			this.image.removeClass("icon_alert");
+			this.image.addClass("icon_confirm");
+			this.btn_cancel.show();
+			
+			this.callback = callback;	
+			
+			this.el.show();
+		},
+		
+		alert: function (title, text1, text2, callback) {
+			this.title.html(title);
+			
+			if (text2) {
+				this.text.html(text1 + "<br>" + text2);
+				this.text.css("line-height", "23px");
+			}
+			else {
+				this.text.html(text1);
+				this.text.css("line-height", "36px");
+			}
+			
+			this.image.removeClass("icon_confirm");
+			this.image.addClass("icon_alert");			
+			this.btn_cancel.hide();
+			
+			this.callback = callback ? callback : null;
+			
+			this.el.show();
+		}
+	});		
+	
+	Dialog.databox = function(title, callback, config) {
+		config = config || {};
+		
+		if (!this.instance) {
+			this.instance = new $.fm.DialogClass();
+		}
+		this.instance.databox(title, callback, config);
+	};
+	
+	Dialog.confirm = function(title, text, callback) {
+		if (!this.instance) {
+			this.instance = new $.fm.DialogClass();
+		}
+		this.instance.confirm(title, text, callback);
+	};
+	
+	Dialog.alert = function(text1, text2, callback) {
+		if (!this.instance) {
+			this.instance = new $.fm.DialogClass();
+		}
+		this.instance.alert("鎻愰啋", text1, text2, callback);
+	};
+	
+	Dialog.wait = function(text) {
+		if (!this.instance) {
+			this.instance = new $.fm.DialogClass();
+		}
+		this.instance.wait("鎻愰啋", text1, text2);		
+	};
diff --git a/WebRoot/js/extend.js b/WebRoot/js/extend.js
new file mode 100644
index 0000000..08820a6
--- /dev/null
+++ b/WebRoot/js/extend.js
@@ -0,0 +1,54 @@
+(function ($) {
+
+	Array.prototype.exists = function(prop, value) {
+		if (!value) {
+			value = prop;
+			prop = null;
+		}
+		
+		for (var i = 0; i < this.length; i++) {
+			var line = this[i];
+			line = this[i].record ? this[i].record : this[i];
+			
+			if (prop) {
+				if (line[prop] == value) {
+					return true;
+				}
+			}
+			else {
+				if (line == value) {
+					return true;
+				}
+			}
+		}
+		
+		return false;
+	};
+	
+	Array.prototype.getItem = function(prop, value) {
+		if (!value) {
+			value = prop;
+			prop = null;
+		}
+		
+		for (var i = 0; i < this.length; i++) {
+			var line = this[i];
+			line = this[i].record ? this[i].record : this[i];
+			
+			if (prop) {
+				if (line[prop] == value) {
+					return line;
+				}
+			}
+			else {
+				if (line == value) {
+					return line;
+				}
+			}
+		}
+		
+		return null;
+	};	
+
+
+})(jQuery);
diff --git a/WebRoot/js/grid.js b/WebRoot/js/grid.js
new file mode 100644
index 0000000..627748d
--- /dev/null
+++ b/WebRoot/js/grid.js
@@ -0,0 +1,893 @@
+(function ($) {
+	
+	$.fm.Grid = Control.subClass({
+		template: [
+  	      	'<div id="grid-body" class="grid-body_min">',
+				'<table id="tab_self" cellpadding=0 cellspacing=0 class="tab_self_min">',
+					'<thead id="table_header" class="tab_self_header_min">',
+						'<tr id="header-row" class="grid-header"></tr>',
+						'<tr id="header-row1" class="grid-header"></tr>',
+					'</thead>',	
+					'<tbody id="table_body" class="tab_self_body_min">',
+					'</tbody>',
+				'</table>',
+			'</div>',
+		],
+		template_footer: [
+	  		'<div class="grid-bar" id="grid-toolbar">',
+				'<div class="grid-bar-placeholder" id="grid-toolbar-placehoder">',
+					'<label id="grid-bar_message"></label>',
+				'</div>',
+				'<div class="grid-bar-area">',
+				    '<div class="grid-bar-group">',
+			    		'<div class="grid-button-outer" id="grid-first-outer">',
+			    			'<span class="grid-button grid-btn-first" id="grid-first"></span>', 
+			    		'</div>',
+			    		'<div class="grid-button-outer" id="grid-prior-outer">',
+		    				'<span class="grid-button grid-btn-prior" id="grid-prior"></span>',		    		
+			    		'</div>',
+			    		'<div class="grid-button-outer" id="grid-next-outer">',
+	    					'<span class="grid-button grid-btn-next" id="grid-next"></span>',		    		
+			    		'</div>',
+			    		'<div class="grid-button-outer" id="grid-last-outer">',
+							'<span class="grid-button grid-btn-last" id="grid-last"></span>',		    		
+			    		'</div>',
+			    	'</div>',		 
+			   	
+				   	'<div class="grid-bar-group">',
+				   		'<input type="text" class="grid-bar-edit" id="currentPage" value="0"/>',	
+			    		'/',			   		
+		    			'<label class="grid-bar-label" id="totalPage">0</label>',			    	
+			    	'</div>',
+		    		
+			       	'<div class="grid-bar-group">',
+			    		'<div class="grid-button-outer" id="grid-load-outer">',
+							'<span class="grid-button grid-btn-load" id="grid-load"></span>',		    		
+			    		'</div>',
+			       	'</div>',
+				'</div>',
+		     '</div>'		                  
+		],
+		
+		template_header_indicator: [
+		    '<td class="grid-indicator">',
+		    	'<div id="header-indicator" class="grid-hd-indicator-inner"></div>',
+		    '</td>'
+		],
+		
+		template_header_cell: [
+			'<td class="grid-hd-cell">',
+				'<div id="header-cell" class="grid-hd-cell-inner"></div>',
+			'</td>'
+		],
+		
+		template_body_indicator: [
+		    '<td class="grid-cell">',
+				'<div id="indicator-body" class="grid-cell-inner grid-indicator-unselected" />',
+			'</td>'
+		],	
+		
+		init: function(options) {
+    		this.headerHeight = 32;
+    		this.footerHeight = 31;
+    		this.limit = 15;
+    		this.colunmUnitWidth = 100;
+    		this.indicatorWidth = 30;
+			this.rowHeight = 23.4;
+			this.editable = false;
+			this.editors = {};
+			this.usedWidth = 0;
+			this.showPage = false;
+			this.hasSubTitle = false;
+			this.showIndicator = true;
+			this.showToolBar = true;
+			this.multiSelect = false;
+			this.singleSelect = true;
+			this.enableAllSelect = false;
+			this.selected = null;
+			this.selectedArray = [];
+			this.dataObject = [];
+			this.rows = [];
+			this.headerFixed = false;  //琛ㄥご鏄惁鍥哄畾
+							 
+    		Control.call(this, options);
+    		
+    		this.createElements();
+    		this.refresh();
+    	},
+    	
+    	createElements: function() {
+    		var me = this;
+    		//1.
+    		this.canvas.addClass("grid");
+    		this.bodyHeight = this.rowHeight * this.limit;
+    		this.height = this.headerHeight + this.bodyHeight;
+    		
+    		//2.
+    		this.element = $(this.template.join(""));
+    		this.element.tab_self = $("#tab_self", this.element);
+    		this.element.table_header = $("#table_header", this.element);
+    		this.element.table_body = $("#table_body", this.element);
+    		
+    		this.setGridType(this.headerFixed);
+    		
+    		this.canvas.append(this.element);
+    		
+    		this.createHeader(this.canvas);
+    		this.createBody(this.canvas);
+    		
+    		if (this.showToolBar) {
+    			if (this.customFooter) {
+    				this.customFooter = this.getEl(this.customFooter);
+                	this.createCustomFooter(this.canvas);
+        		}
+    			else {
+    				this.createDefaultFooter(this.canvas);
+    			}
+    		} else {
+    			if (this.customFooter) {
+    				this.customFooter = this.getEl(this.customFooter);
+    				this.customFooter.hide();
+    			}
+    		}
+    		
+    		this.tableBody.scroll(function() {
+    			var left = $(this).scrollLeft();
+				me.table_header.scrollLeft(left);
+    		});
+    	},
+    	
+    	setGridType: function(headerFixed) {
+    		if (headerFixed) {
+    			this.element.attr("class", "grid-body");
+    			this.element.tab_self.attr("class", "tab_self");
+    			this.element.table_header.attr("class", "tab_self_header");
+    			this.element.table_body.attr("class", "tab_self_body");
+    		}
+    	},
+    	
+    	createHeader: function(area) {
+    		var columns = this.columns, me = this, rowspan = 1;
+    		if (!columns) return;
+    		
+    		var header = $('.grid-header', area);
+    		header.height(this.headerHeight);
+    		header.css("line-height", this.headerHeight + "px");
+    		
+    		var row = $('#header-row', area);
+    		var row1 = $('#header-row1', area);
+    		
+    		if (this.titleClass) {
+    			row.attr("class", this.titleClass);
+    			row1.attr("class", this.titleClass);
+    		}
+    		
+    		
+    		this.table_header = $('#table_header', area);
+    		
+    		if(!this.hasSubTitle) {
+    			row1.hide();
+    		}
+    		else{
+    			rowspan = 2;
+    		}
+    		
+			//1.
+    		if (this.showIndicator) {
+    			var template = $(this.template_header_indicator.join(""));
+    			template.attr("rowspan", rowspan);
+    			
+    			var indicator = this.headerIndicator = $('#header-indicator', template);
+    			
+    			if (this.enableAllSelect) {
+    				indicator.addClass("grid-indicator-unselected");
+    				indicator.click(function() {
+    					me.setAllSelect();
+    				});
+    			}
+    			
+    			indicator.width(this.indicatorWidth);
+    			row.append(template);
+    		}
+			
+			//2.
+    		var flag = false, m = 0, colspan, pcolumn;
+        	for (var i = 0; i < columns.length; i++) {
+        		var column = columns[i];
+        		this.usedWidth = this.usedWidth + column.width;
+        		var cell = null;
+        		
+        		if(column.parent) {
+        			flag = true, m++;
+        			
+        			if(column.colspan) {
+        				colspan = column.colspan;
+        				pcolumn = column;
+        			}
+        			
+        			cell = $(this.template_header_cell.join(""));
+        			
+            		cell.body = $('#header-cell', cell);
+            		cell.body.width(column.width);
+            		cell.body.html(column.caption),
+            		
+            		row1.append(cell);
+        		}
+        		else{
+        			cell = $(this.template_header_cell.join(""));
+        			cell.attr("rowspan", rowspan);
+        			
+            		cell.body = $('#header-cell', cell);
+            		cell.body.width(column.width);
+            		cell.body.html(column.caption),
+            		
+            		row.append(cell);
+        		}
+        		
+        		if(flag && m % colspan == 0) {
+        			row.append("<td colspan='" + colspan + "' align='center' style='border-bottom: 1px solid #A3C0E8; border-right: 1px solid #A3C0E8'>" + pcolumn.parent + "</td>");
+        			flag = false;
+        			m = 0;
+        		}
+        	}
+    	},
+    	
+    	createBody: function(element, columns) {
+    		this.body = $('#grid-body', element);
+    		this.body.height(this.height);
+    		
+    		this.tableBody = $('#table_body', element);
+    	},
+    	
+    	createDefaultFooter: function(element) {
+    		var me = this;
+    		var footer = $(this.template_footer.join(""));
+    		var toolbar = element.toolbar = $('#grid-toolbar', element);
+    		
+    		var placeholder =  $('#grid-toolbar-placehoder', footer);
+    		placeholder.width(200);
+    		
+    		var btn_first = toolbar.btn_first = $('#grid-first', footer);
+    		var btn_prior = toolbar.btn_prior = $('#grid-prior', footer);
+    		var btn_next = toolbar.btn_next = $('#grid-next', footer);
+    		var btn_last = toolbar.btn_last = $('#grid-last', footer);
+    		var btn_load = toolbar.btn_load = $('#grid-load', footer);
+    		btn_load.active = true;
+    		
+    		var currentPage = toolbar.currentPage = $('#currentPage', footer);
+    		var totalPage = toolbar.totalPage = $('#totalPage', footer);    		
+    		var information = toolbar.information = $('#grid-bar_message', footer);
+    		
+    		me.initButton(btn_first, me.firstPage);
+    		me.initButton(btn_prior, me.priorPage);
+    		me.initButton(btn_next, me.nextPage);
+    		me.initButton(btn_last, me.lastPage);    		
+    		me.initButton(btn_load, me.refresh);
+    		
+    		information.html("娌℃湁鏁版嵁");
+    		element.append(footer);
+    	},
+    	
+    	createCustomFooter: function(canvas, array) {
+    		this.customFooter.remove();
+    		this.canvas.append(this.customFooter);
+    		this.customFooter.show();
+    	},
+    	
+    	setURL: function(url) {
+    		this.url = url;
+    		this.refresh();
+    	},
+    	
+    	refresh: function() {
+			this.tableBody.empty();
+    		var me = this;
+    		this.selected = null; this.selectedArray = [];
+    		
+    		if (!this.url) {
+    			return;
+    		}
+    		
+    		Server.getData(this.url, function(data, page) {
+    			Loading.hide();
+    			
+				if (me.onGetData) {
+					data = me.onGetData(data);
+				}
+				me.loadData(data, page);
+			});			
+		},
+		
+		fireDataChange: function() {
+			if (this.onDataChagne) {
+				this.onDataChagne();
+			} 
+		},
+		
+		loadData: function(array, page) {
+			this.tableBody.empty();
+			this.rows = [];
+			this.dataObject = [];
+		
+			if (!array || !array.length){
+				return;
+			}
+			
+			$('#grid-bar_message', this.canvas).html("鎬诲叡 " + array.length + " 鏉¤褰�");
+        	
+        	for (var m = 0; m < array.length; m++) {
+        		var data = array[m];
+        		var row = this.loadLine(data, m);
+        		
+        		this.tableBody.append(row.element);
+        		this.rows.push(row);
+        		this.dataObject.push(row.data);
+        	}
+        	
+        	if (this.showPage && page) {
+        		this.loadPage(page);
+        	}
+        	
+        	if (this.afterLoad){
+        		this.afterLoad(array, this.selected);
+        	}
+        	
+        	if (this.defaultSelectedIdx) {
+        		this.select(this.defaultSelectedIdx - 1);
+        	}
+        	
+        	if (this.columnsAverage) {
+        		this.columnsAverage(this.rows);
+        	}
+        	
+        	this.bodyIndicator = $("#indicator-body", this.canvas);
+		},
+		
+		loadLine: function(data, index) {
+			var me = this; var columns = this.columns;
+			
+        	var row = {"index": index};
+       		
+        	var rowEl = $('<tr class="l-grid-row"></tr>');
+    		rowEl.data('row', row);
+    		
+    		if (!me.doubleClickSelect) {
+        		rowEl.click(function() {
+        			if(me.singleSelect)
+        				me.setRowSelected.call(me, $(this).data('row'));
+        		});
+    		}
+    		else {
+        		rowEl.dblclick(function() {
+        			if(me.singleSelect)
+        				me.setRowSelected.call(me, $(this).data('row'));
+        		});
+    		}
+    		
+    		rowEl.hover(
+    			function() {
+    				$(this).addClass("grid-row-over");
+    			},
+    			function() {
+    				$(this).removeClass("grid-row-over");
+    			}
+    		);
+    		
+    		row['element'] = rowEl;
+    		var dataObject = new DataObject(data);
+    		dataObject.onDataChange = function() {
+    			me.refreshLine(row, rowEl);
+    		}
+    		row['data'] = dataObject;
+    		
+    		
+    		if (this.onLineRender) {
+    			this.onLineRender(row, data);
+    		}
+    		
+    		var cells = me.loadLineCells(row, data, columns);
+    		row['cells'] = cells;
+
+    		if (row.select) {
+    			row.select = false;
+    			this.setRowSelected(row);
+    		}
+    		
+    		return row;
+		},
+		
+		loadLineCells: function(row, data, columns) {
+			var cells = new Array(length);
+
+			//1.
+			if (this.showIndicator) {
+				var indicator = $(this.template_body_indicator.join(""));
+				row.indicator = $("#indicator-body", indicator);
+				
+				row.indicator.width(this.indicatorWidth);
+				row.element.append(indicator);
+				
+			}
+			
+			//2.
+        	for (var i = 0; i < columns.length; i++) {
+        		var column = columns[i];
+        		
+        		var cell = new $.fm.Grid.Cell({
+        			grid: this,
+        			column: column,
+        			row: row,
+        			value: data[column.field]
+        		});
+        		row.element.append(cell.element);
+        		
+        		cells[i] = cell;
+        	}	
+        	
+        	return cells;
+		},
+		
+		refreshLine: function(row, rowEl) {
+			var cells = row.cells;
+			
+			for (var i = 0; i < cells.length; i++) {
+				var cell = cells[i];
+				cell.refresh();
+			}
+			
+		},
+		
+		loadPage: function(page) {
+			this.page = page; var bar = this.canvas.toolbar;
+			
+			bar.currentPage.val(page.pageno);
+			bar.totalPage.text(page.pagecount);
+			
+			var message = '娌℃湁鏁版嵁';
+			if (page.pagecount > 0) {
+				message = '[ 鏄剧ず' + page.beginrecordno + '-' + page.endrecordno + ' / ' + page.recordcount + '鏉� ]';				
+			}
+			
+			bar.information.html(message);	
+			
+			this.setButtonActive(bar.btn_first, page.pageno > 1);
+			this.setButtonActive(bar.btn_prior, page.pageno > 1);
+			this.setButtonActive(bar.btn_next, page.pageno < page.pagecount);			
+			this.setButtonActive(bar.btn_last, page.pageno < page.pagecount);	
+		},
+
+		pageTo: function(pageNo) {
+			var start = this.url.indexOf('pageno');
+			var end = this.url.indexOf('&', start);
+			var replaceStr = this.url.substring(start, end);
+			this.url = this.url.replace(replaceStr, 'pageno=' + pageNo);
+			
+			this.refresh();
+		},
+		
+		firstPage: function() {
+			this.pageTo(1);
+		},
+		
+		priorPage: function() {
+			this.pageTo(this.page.pageno - 1);
+		},
+		
+		nextPage: function() {
+			this.pageTo(this.page.pageno + 1);
+		},
+		
+		lastPage: function() {
+			this.pageTo(this.page.pagecount);
+		},
+		
+		setRowSelected: function(row) {
+			if (this.enableAllSelect && this.allSelect) {
+				this.clearAllSelected();
+			}
+			
+			if ($.isNumeric(row)) {
+				row = this.rows[row];
+			}
+			
+			if (!row.select) {
+				if (this.selected) {
+					this.doSetRowUnselected(this.selected);
+				}
+				
+				this.doSetRowSelected(row);
+			}
+			else {
+				this.doSetRowUnselected(row);
+				this.allSelect = false;
+			}
+			
+			if (this.onSelect) {
+				this.onSelect(this.allSelect, this);
+			}
+		},
+		
+		toggleAllSelected: function() {
+			if (!this.multiSelect) {
+				return;
+			}
+			
+			//1. clear single selected
+			if (this.selected) {
+				this.doSetRowUnselected(this.selected);
+			}
+
+			//2. set select
+			var select = this.allSelect = !this.allSelect;
+			
+			var rows = this.rows;
+			for (var i = 0; i < rows.length; i++) {
+				rows[i].select = select;
+			}
+			
+			//3. toggle class
+			if (select) {
+				this.headerIndicator.removeClass("grid-indicator-unselected");
+				this.headerIndicator.addClass("grid-indicator-selected");
+				
+				this.bodyIndicator.removeClass("grid-indicator-unselected");
+				this.bodyIndicator.addClass("grid-indicator-selected");
+			}
+			else {
+				this.headerIndicator.removeClass("grid-indicator-selected");
+				this.headerIndicator.addClass("grid-indicator-unselected");	
+				
+				this.bodyIndicator.removeClass("grid-indicator-selected");
+				this.bodyIndicator.addClass("grid-indicator-unselected");
+			}
+			
+			//4. fire event				
+			if (this.onSelect) {
+				this.onSelect(this.allSelect, this);
+			}
+		},		
+		
+		doSetRowSelected: function(row) {
+			//1. add to selected
+			row.select = true;
+			if (!this.multiSelect) {
+				this.selected = row;
+			}
+			
+			//2. set selected class
+			if (row.indicator) {
+				row.indicator.removeClass("grid-indicator-unselected");
+				row.indicator.addClass("grid-indicator-selected");
+			}
+			row.element.addClass("grid-row-selected");
+			
+			//3. fire event
+			if (this.onRowSelected) {
+				this.onRowSelected(row);
+			}
+		},
+		
+		doSetRowUnselected: function(row) {
+			//1. set selected null
+			row.select = false;
+			this.selected = null;
+			
+			//2. remove selected class
+			if (row.indicator) {
+				row.indicator.removeClass("grid-indicator-selected");
+				row.indicator.addClass("grid-indicator-unselected");
+			}
+			row.element.removeClass("grid-row-selected");
+		},
+		
+		getSelectedRow: function() {
+			//1. single select
+			if (!this.multiSelect) {
+				return this.selected ? this.selected : null;
+			}
+			
+			//2. multiple select
+			var result = [], rows = this.rows;
+			for (var i = 0; i < rows.length; i++) {
+				var row = rows[i];
+				if (row.select) {
+					result.push(row);
+				}
+			}
+			return result;
+		},
+		
+		getSelected: function() {
+			//1. single select
+			if (!this.multiSelect) {
+				return this.selected ? this.selected.data : null;
+			}
+			
+			//2. multiple select
+			var result = [], rows = this.rows;
+			for (var i = 0; i < rows.length; i++) {
+				var row = rows[i];
+				if (row.select) {
+					result.push(row.data);
+				}
+			}
+			return result;
+		},
+		
+    	initButton: function(button, handler) {
+			var me = this;
+			
+			button.hover(
+				function(){			
+					if (button.active) {
+						button.addClass('grid-button-over');
+					}
+				}, function(){
+					button.removeClass('grid-button-over');    			
+				}
+			); 
+			
+			button.click(function() {
+				if (button.active) {
+					handler.call(me);
+				}
+    		});
+    	},
+    	
+		setButtonActive: function(button, active) {
+			button.active = active;
+			
+			if (active) {
+				button.removeClass("grid-btn-disable");
+			}
+			else {
+				button.addClass("grid-btn-disable");
+			}
+		},
+		
+		editCell: function (cell, e) {
+			/*if (this.activeCell == cell) {
+				return;
+			}*/
+			
+			var me = this;
+			
+//			var submitResult = me.submitCell();
+//			if (!submitResult) return;
+			
+			me.activeCell = cell;
+			
+            var column = cell.column;
+            var editor = me.editors[column.type];
+            
+      //      if (!editor) {
+      //      	editor = ControlCreator.create(column); 
+            	editor = $("#input", ControlCreator.create(column).editor);
+            	editor.height(this.rowHeight);
+            	
+            	editor.on("blur", function() {
+            		return me.submitCell();
+            	});
+            	
+            	this.canvas.append(editor);
+            	me.editors[column.type] = editor;
+      //      }
+            	
+            var offset = cell.element.offset();
+            var parentOffset = me.canvas.offset();
+            
+            editor.val(cell.value);
+            editor.css({
+                position: 'absolute',
+            	left: offset.left - parentOffset.left,
+            	width: column.width - 2,
+            	top: offset.top - parentOffset.top + 1
+            });
+            
+//        	RootParent.registerActiveEditor(editor);
+            editor.focus();
+            
+            me.activeEditor = editor;
+		},
+		
+        submitCell: function () {
+			var success = false;
+			
+			var activeEditor = this.activeEditor;
+			
+			if (!this.activeCell || !activeEditor) return true;
+			
+			var value = activeEditor.val();
+			var text = activeEditor.getText ? activeEditor.getText() : null;
+			
+			var eventResult = this.fire('setValue', this.activeCell, value, text);
+			
+			if (eventResult == undefined || eventResult == null || eventResult) {
+				this.activeCell.setValue(value, text);
+				this.activeEditor.hide();
+				this.fireDataChange();
+				
+				this.activeCell = null;
+				this.activeEditor = null;
+				
+				success = true;
+			}
+			
+			return success;
+        },
+        
+        callRowFunction: function(eventFunc, internalRowFunc, record, index) {
+        	var me = this;
+        	
+        	if (eventFunc) {
+        		eventFunc(record, function() {
+        			internalRowFunc.call(me, record, index);
+        		});
+        	}
+        	else {
+        		internalRowFunc.call(me, record, index);
+        	}
+        	
+        	this.fireDataChange(record);
+        },
+        
+        appendRow: function(record) {
+        	this.callRowFunction(this.onAddRow, this.doAppendRow, record, 0);
+        },
+        
+        doAppendRow: function(record) {
+        	var index = this.rows.length;
+        	var row = this.loadLine(record, index);
+        	
+        	this.tableBody.append(row.element);
+    		this.rows.push(row);
+    		this.dataObject.push(row.data);
+    		
+    		this.setRowSelected(row);
+    		
+    		if (this.rows.length > this.limit) {
+    			this.deleteRow(0);
+    		}
+        },
+        
+        insertRow: function(record, index) {
+        	this.callRowFunction(this.onAddRow, this.doInsertRow, record, index);
+        },
+        
+        doInsertRow: function(record, index) {
+        	var index = this.rows.length;
+        	var row = this.loadLine(data, index);
+        	var baseRow = this.rows[index];
+        	
+        	baseRow.element.prepend(row.element);
+        	this.rows.splice(index, 0, row);
+        	this.dataObject.splice(index, 0, row.data);
+    		
+    		this.setRowSelected(row);
+    		
+    		if (this.rows.length > this.limit) {
+    			this.deleteLastRow();
+    		}    		
+        },
+        
+        deleteRow: function(index) {
+        	this.callRowFunction(this.onDeleteRow, this.doDeleteRow, null, index);
+        },
+        
+        doDeleteRow: function(me, index) {
+        	var row = this.rows[index];
+        	
+        	this.rows.splice(index, 1);
+        	this.dataObject.splice(index, 1);
+        	row.element.remove();
+        },
+        
+        deleteLastRow: function() {
+        	this.callRowFunction(this.onDeleteRow, this.doDeleteLastRow, null, 0);
+        },
+        
+        doDeleteLastRow: function() {
+        	var row = this.rows.pop(); 
+        	this.dataObject.pop(); 
+        	row.element.remove();
+        },
+        
+        empty: function() {
+    		if (this.customFooter) {
+    			this.customFooter.hide();
+    			this.customFooter.remove();
+    			$("body").append(this.customFooter);
+    		}
+    		
+    		this.data = null;
+    		this.dataObject = [];
+    		this.rows = [];
+    		this.canvas.empty();
+    	},
+    	
+    	getData: function() {
+    		return this.dataObject;
+    	}
+	});
+	
+    
+    $.fm.Grid.Cell = Control.subClass({
+		template: [
+		    '<td class="grid-cell">',
+		    	'<div class="grid-cell-inner" />',
+		    '</td>'
+		],    	
+		
+    	init: function(options) {
+			Control.call(this, options); 
+			this.width = this.column.width;
+			
+			this.createElement();
+    	},
+    	
+    	createElement: function() {
+    		var me = this, column = this.column; 
+    		
+    		var element = $(me.template.join("")); me.element = element;
+    		
+			element.body = $('div', element);
+			element.body.width(column.width);
+			element.body.attr("align", column.align || "center");
+			
+			this.renderValue();
+			
+			if (me.grid.editable || me.column.editable) {
+				if (me.grid.quickEdit) {
+					element.click(function() {
+						me.grid.editCell(me);
+					});				
+				}
+				else {
+					element.dblclick(function() {
+						me.grid.editCell(me);
+					});					
+				}				
+			}
+    	},
+    	
+    	renderValue: function() {
+    		var element = this.element; var column = this.column;
+    		
+			if (column.render) {
+				column.render(element.body, this.value, this.row, this.grid);
+			}
+			else {
+				if(column.field.substring(0, 8) == 'constant'){
+					element.body.html(column.field.substring(8));
+				}
+				else{
+					element.body.html(this.value);
+				}
+			}
+    	},
+    	
+    	refresh: function() {
+    		var fieldName = this.column.field;
+    		var dataObject = this.row.data;
+    		
+    		this.value = dataObject.getValue(fieldName);
+    		this.renderValue();
+    	},
+    	
+    	setValue: function(value, text) {
+    		var fieldName = this.column.field;
+    		var dataObject = this.row.data;
+    		
+    		this.value = value;
+    		this.text = text;
+    		dataObject.setValue(fieldName, value);
+    		
+    		this.element.body.html(this.text || this.value);
+    	},
+    	
+    	setControl: function(control) {
+    		this.addChild(control);
+    	}
+    });
+		
+})(jQuery);
\ No newline at end of file
diff --git a/WebRoot/js/jquery-1.7.2.min.js b/WebRoot/js/jquery-1.7.2.min.js
new file mode 100644
index 0000000..16ad06c
--- /dev/null
+++ b/WebRoot/js/jquery-1.7.2.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.2 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test("聽")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
+a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
+.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
\ No newline at end of file
diff --git a/WebRoot/js/loading.js b/WebRoot/js/loading.js
new file mode 100644
index 0000000..67c828f
--- /dev/null
+++ b/WebRoot/js/loading.js
@@ -0,0 +1,92 @@
+
+	// ================================Loading===================================//
+	Loading = $.fm.LoadingClass = Control.subClass({
+		template: [
+		    '<div class="loading_mask" style="display: none" align="center">',
+			    '<div id="area" class="loading_area" align="center">',
+			    	'<div class="loading_image"></div>',
+			    '</div>',
+		    '</div>'
+		],
+		itemTemplate: '<div class="loading_text"></div>',
+		itemList: {},
+	
+		init: function(options) {
+			options = options ? options : {};
+			Control.call(this, options);
+			this.canvas = $(window.top.window.document.body);
+			
+			this.createEl();
+		},
+		
+		createEl: function() {
+			var el = this.el = $(this.template.join(""));
+			this.area = $("#area", el);
+			this.canvas.append(this.el);
+		},
+		
+		show: function (code, text) {
+			text = text || code;
+			code = code || "item";
+			
+			var item = this.itemList[code];
+			
+			if (!item) {
+				item = this.itemList[code] = $(this.itemTemplate);
+				this.area.append(item);
+			}
+			
+			item.html(text);
+			this.el.show();
+		},
+		
+		hide: function(code) {
+			if (code) {
+				var item = this.itemList[code];
+				if (item) {
+					item.remove();
+				}
+				
+				for (var n in this.itemList) {
+					return;
+				}
+				
+				this.el.hide();
+				return;
+			}
+			
+			this.el.hide();
+			
+			for (var n in this.itemList) {
+				var item = this.itemList[n];
+				if (item.remove) {
+					item.remove();
+				}
+			}
+			this.itemList = {};
+		}
+	});		
+	
+	Loading.show = function(code, text) {
+		var instance = window.top.window.Loading.instance || this.instance;
+		
+		if (!instance) {
+			instance = this.instance = new $.fm.LoadingClass();
+		}
+		
+		instance.show(code, text);
+	};
+	
+	Loading.hide = function(code) {
+		var instance = window.top.window.Loading.instance || this.instance;
+		
+		if (!instance) {
+			instance = this.instance = new $.fm.LoadingClass();
+		}
+		
+		instance.hide(code);
+	};
+
+	$(window.document).ready(function() {
+		Loading.hide();
+	});
diff --git a/WebRoot/js/tree.js b/WebRoot/js/tree.js
new file mode 100644
index 0000000..701f8f7
--- /dev/null
+++ b/WebRoot/js/tree.js
@@ -0,0 +1,475 @@
+(function ($) {
+	
+	Tree = $.fm.Tree = Control.subClass({
+		template: [
+	    	'<div class="tree-inner">',
+	    		'<ul id="tree-body" class="tree-body">',
+	    	'</div>',	
+		],
+		
+		init: function(options) {
+			this.checkable = false;
+			this.autoExpended = true;
+			this.childrenIndex = 0;
+			Control.call(this, options);
+			
+			this.createElements();
+			
+			if (this.url) {
+    			var me = this;
+				Server.getData(this.url, function(data) {
+					Loading.hide();
+					
+					if (me.onGetData) {
+						data = me.onGetData(data);
+					}
+					me.loadData(data);
+				});				
+			}
+			else if (this.data) {
+				this.loadData(this.data);
+			}
+		},
+		
+		createElements: function() {
+    		var me = this;
+    		
+    		this.canvas.addClass("tree");
+    		
+    		var tree = $(this.template.join(""));
+    		this.body = $("#tree-body", tree);
+    		
+    		this.canvas.append(tree);
+		},
+		
+		loadData: function(array) {
+			this.data = this.parseArray(array);
+		//	this.parseArray(array)
+			this.doLoadData(null, this.data, 0);
+		},
+		
+		parseArray: function(array) {
+			var i, l,
+	            id = "id",
+	            parent = "parentid",
+	            children = "children";
+	        if (!id || id == "" || !array) return [];
+	
+	        if ($.isArray(array)) {
+	            var r = [];
+	            var tmpMap = {};
+	            for (i = 0; i < array.length; i++) {
+	                tmpMap[array[i][id]] = array[i];
+	            }
+	            for (i = 0; i < array.length; i++) {
+	                if (tmpMap[array[i][parent]] && array[i][id] != array[i][parent]) {
+	                    if (!tmpMap[array[i][parent]][children])
+	                        tmpMap[array[i][parent]][children] = [];
+	                    tmpMap[array[i][parent]][children].push(array[i]);
+	                } else {
+	                    r.push(array[i]);
+	                }
+	            }
+	            return r;
+	        } else {
+	            return [array];
+	        }
+		},
+		
+		doLoadData: function(parent, array, level) {
+        	var node;
+        	var cnt = array.length || 1;
+        	
+        	for (var i = 0; i < cnt; i++) {
+        		var line = array[i];
+        		
+        		node = new $.fm.Tree.Node({
+        			node_checkable: this.checkable,
+        			tree: this,
+        			parent: parent,
+        			isLast: i == cnt - 1,
+        			isRoot: !parent,
+        			isLeaf: !line.children,
+        			level: level,
+        			expended: line.children && (this.autoExpended || line.expended),
+        			record: line
+        		});
+        		
+        		node.isRoot ? this.body.append(node.element) : parent.element.children.append(node.element);
+        		
+        		if (line.children) {
+        			this.doLoadData(node, line.children, level + 1);
+        		}
+        	}
+		},
+		
+		addNode: function(parent, data) {
+			data['tree'] = this;
+			data['parent'] = parent; 
+			data['isLast'] = true; 
+			data['isLeaf'] = (data['isLeaf'] != null) ? data['isLeaf'] : true;
+    		
+			if (parent) {
+				data['level'] = parent.level + 1;
+				
+				var lastNode = parent.children ? parent.children[parent.children.length - 1] : null;
+				if (lastNode) {
+					lastNode.setLast(false);
+				}
+			}
+			
+    		var node = new $.fm.Tree.Node(data);
+    //		node.render();
+    		
+    		if (parent) {
+    			parent.element.children.append(node.element); 
+    			parent.expand(); 
+    		}
+    		else {
+    			this.element.ul.append(node.element);
+    		}	
+    		
+    		this.doNodeSelect(node);
+		},
+		
+		doNodeSelect: function(node) {
+			if (this.selected) {
+				this.selected.unSelect();
+			}
+			
+			node.select();
+			this.selected = node;
+			
+			if (this.onNodeSelect) {
+				this.onNodeSelect(node);
+			}
+			
+		},
+		
+		onNodeSelectCheckable: function(node) {
+			node.selectCheckable(node);
+		},
+		
+		getSelectAll: function() {
+			var allcheckbox = $("input[type='checkbox']", this.body);
+			var selectAll = [];
+			for (var i = 0; i < allcheckbox.length; i++) {
+				var checkbox = $(allcheckbox.get(i));
+				if (checkbox.is(':checked')) {
+					selectAll.push(checkbox.attr('node_name'));
+				}
+			}
+			return selectAll;
+		},
+		
+		setSelectNodes: function(array) {
+			if (array.length > 0) {
+				for (var i = 0; i < array.length; i++) {
+					for (var aa in array[i]) {
+						this.setSelectNode(array[i][aa]);
+					}
+				}
+			}
+		},
+		
+		setSelectNode: function(node_name) {
+			var allcheckbox = $("input[node_name='" + node_name + "']", this.body);
+			allcheckbox.prop("checked", true);
+		},
+		
+		cancelSelectNodes: function() {
+			var allcheckbox = $("input[type='checkbox']", this.body);
+			allcheckbox.prop("checked", false);
+		}
+		
+	});
+	
+	
+	$.fm.Tree.Node = Control.subClass({
+		template_node: [
+	    	'<li>',
+				'<div id="node-body" class="l-body"></div>',
+			'</li>'	
+		],
+		template_node_box: '<div class="l-box" />',
+		template_node_icon: '<div id="icon" class="l-box l-tree-icon"></div>',
+		template_node_text: '<label id="text" class="node"></label>',
+		template_node_children:	'<ul id="children" class="l-children"></ul>',
+		template_node_checkbox: [
+		    '<div class="l-box" style="position: relative; width: 16px;">',
+				'<div style="position: absolute; top: 0px; left: 0px; width: 16px; height: 22px;">',
+					'<label><input style="vertical-align: -2px;" type="checkbox"/></label>',
+				'</div>',
+				'<div style="position: absolute; top: 0px; left: 0px; width: 16px; height: 22px;"></div>',
+			'</div>'
+		],
+				
+		init: function(options) {
+			this.selected = false;
+			this.expended = false;
+			this.children = [];
+			this.autoSize = false;
+			this.node_checkable = false;
+			
+			Control.call(this, options);
+			this.createElements();
+		},
+		
+		createElements: function() {
+			var me = this;
+			var element = this.element = this.doCreateElements();
+			
+			if (element.button) {
+				element.button.click(function() {
+					if (me.expended) {
+						me.collapse();
+					}
+					else {
+						me.expand();
+					}
+				});
+			}
+			
+			/*window.oncontextmenu=function(e){
+				//鍙栨秷榛樿鐨勬祻瑙堝櫒鑷甫鍙抽敭 寰堥噸瑕侊紒锛�
+				e.preventDefault();
+			}*/
+			
+			element.text.click(function(e) {
+				if (!me.selected) {
+					me.tree.doNodeSelect(me);
+				}
+				
+				if (me.node_checkable) {
+					me.tree.onNodeSelectCheckable(me);
+				}
+				
+			});
+		},
+		
+		doCreateElements: function() {
+			//1. create element
+			var element = $(this.template_node.join(""));
+			var body = $("#node-body", element);
+			
+			if (this.isRoot) {
+				element.addClass("l-onlychild");
+			}
+			else if (this.isLast) {
+				element.addClass("l-last");
+			}
+			
+			//2. create box 
+			var me = this;
+			var parentlevel = this.parentLevel(me);
+            for (var i = 0; i <= this.level; i++) {
+            	var box = $(this.template_node_box);
+            	/*if (me.record.code == "test04") {
+            		var aza=1;
+            	}*/
+            	if (this.isLeaf) {
+            		if (i == 0) {
+            			if (this.parent) {
+            				this.isLast ? box.addClass("l-note-last") : box.addClass("l-note");
+            			}
+            		}
+            		else if ((i < this.level) && (this.parent && !me.parent.isLast)) {
+            			if (!parentlevel || i < this.level - parentlevel) {
+            				box.addClass("l-line");
+            			}
+            		}
+            		else {
+            			me = me.parent;
+            			if (me.isLast) {
+            				parentlevel = this.parentLevel(me);
+            			}
+            		}
+            		body.prepend(box);
+            	}
+            	else {
+            		if (i == 0 && (this.parent && !this.parent.isLast) && this.parent.level > 0) {
+            			box.addClass("l-line");
+            		}
+            		else if (i == (this.level)) {
+            			this.expended ? box.addClass("l-expandable-open") : box.addClass("l-expandable-close");
+            			element.button = box;
+            		}
+            		else if (i && (i <= this.level) && (me.parent && !me.parent.isLast) && me.parent.level > 0) {
+            			if (parentlevel && i == parentlevel - 1) {
+            				box.addClass("l-line");
+            			}
+            		}
+            		else {
+            			me = me.parent;
+            			if (!me.isLast) {
+            				parentlevel = this.parentLevel(me);
+            			}
+            		}
+            	//	box.addClass("aa" + i);
+            	//	box.attr("name", me.record.code);
+            		if (i == this.level) {
+            			body.append(box);
+            		}
+            		else {
+            			body.prepend(box);
+            		}
+            	}
+	        }
+            
+            //3. create icon
+        	element.icon = $(this.template_node_icon);
+        	if (this.tree.renderNodeIcon) {
+        		this.tree.renderNodeIcon(element.icon);
+        	}
+        	else if (this.isLeaf) {
+        		element.icon.addClass("tree-body-icon-leaf");
+        	}
+        	else {
+        		this.expended ? element.icon.addClass("tree-body-icon-folder-open") : element.icon.addClass("tree-body-icon-folder");
+        	}
+        	body.append(element.icon);
+        	
+        	//4. create text
+        	element.text = $(this.template_node_text);
+        	if (this.tree.renderNodeText) {
+        		this.tree.renderNodeText(element.text, this.record ? this.record : this);
+        	}
+        	else {
+        		var value = this.name || (this.record ? this.record.name : "empty");
+        		element.text.html(value)
+        	}
+        	
+        	// create checkbox
+        	if (this.node_checkable) {
+        		var node_checkbox = $(this.template_node_checkbox.join(""));
+        		node_checkbox.input = $("input", node_checkbox);
+        		node_checkbox.input.attr("node_name", this.record.id);
+        		element.text.prepend(node_checkbox);
+        	}
+        	
+        	body.append(element.text);
+        	
+            //5. create children
+            if (!this.isLeaf) {
+            	var children = element.children = $(this.template_node_children);
+            	this.expended ? children.show() : children.hide();
+            	element.append(children);
+            }
+        	
+        	return element;
+		},
+		
+		parentLevel: function(me) {
+			var current = me;
+			for (var i = 1; i <= current.level; i++) {
+				if (me.parent && me.parent.isLast) {
+					return me.parent.level;
+				}
+				me = me.parent;
+			}
+			return null;
+		},
+		
+		selectCheckable: function(me) {
+			//1. 閫変腑/鍙栨秷鎵�鏈夊瓙鏂囦欢
+			var allcheckbox = $("input[type='checkbox']", me.element);
+			
+			if (allcheckbox.prop("checked")) {
+				allcheckbox.prop("checked", false);
+			}
+			else {
+				allcheckbox.prop("checked", true);
+			}
+			
+			//2. 閫変腑/鍙栨秷鎵�鏈変笂绾ф枃浠�
+			var current = me;
+			me = me.element.parent();
+			for (var i = 0; i < current.level; i++) {
+				var div = $("div", me.parent()[0]);
+				var allcheckbox_2 = $("input[type='checkbox']", div[0]);
+				
+				allcheckbox_2.prop("checked", this.isSelectParent($("input[type='checkbox']", me)));
+				
+				me = me.parent().parent();
+			}
+		},
+		
+		isSelectParent: function(allcheckbox) {
+			for (var i = 0; i < allcheckbox.length; i++) {
+				var checkbox = $(allcheckbox.get(i));
+				if (checkbox.is(':checked')) {
+					return true;
+				}
+			}
+			return false;
+		},
+		
+		getSelectAllNode: function() {
+			
+		},
+		
+		expand: function() {
+			this.expended = true;
+			
+			this.element.button.removeClass("l-expandable-close").addClass("l-expandable-open");
+			this.element.icon.removeClass("tree-body-icon-folder").addClass("tree-body-icon-folder-open");
+			this.element.children.css({display: 'block'});
+            
+			if (this.tree.afterExpand) {
+				this.tree.afterExpand(this);
+			}
+		},
+		
+		collapse: function() {
+			this.expended = false;
+			
+			this.element.button.removeClass("l-expandable-open").addClass("l-expandable-close");
+			this.element.icon.removeClass("tree-body-icon-folder-open").addClass("tree-body-icon-folder");
+			this.element.children.css({display: 'none'});
+            
+			if (this.tree.afterCollapse) {
+				this.tree.afterCollapse(this);
+			}
+		},
+		
+		select: function() {
+			this.selected = true;	
+			
+			this.element.icon.addClass("node-selected");
+			this.element.text.addClass("node-selected");
+		},
+		
+		unSelect: function() {
+			this.selected = false;	
+			
+			this.element.icon.removeClass("node-selected");
+			this.element.text.removeClass("node-selected");
+		},
+		
+		setLast: function(flag) {
+			if (this.isLast == flag) {
+				return;
+			}
+			
+			this.isLast = flag;
+			
+			if (this.element) {
+				if (flag) {
+					this.element.line.removeClass('l-note');
+					this.element.line.addClass('l-note-last');	
+					
+				}
+				else {
+					this.element.line.removeClass('l-note-last');	
+					this.element.line.addClass('l-note');					
+				}
+			}
+		},
+		
+		render: function() {
+			
+		}
+		
+	});
+	
+})(jQuery);
\ No newline at end of file
diff --git a/WebRoot/page/api.html b/WebRoot/page/api.html
new file mode 100644
index 0000000..2261c2f
--- /dev/null
+++ b/WebRoot/page/api.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/main.css" rel="stylesheet">
+	    
+	    <script type="text/javascript">
+	    
+		</script>	    
+	</head>
+
+<body>
+	this is API;
+
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/demo.html b/WebRoot/page/demo.html
new file mode 100644
index 0000000..75d46af
--- /dev/null
+++ b/WebRoot/page/demo.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/demo.css" rel="stylesheet">
+		<script src="../js/jquery-1.7.2.min.js"></script>
+	    
+	    <script type="text/javascript">
+	    
+	    	function pageTo(target) {
+	    		$("#demo-content").attr("src", "./demo_container/" + target);
+	    	}
+
+	    	$(document).ready(function() {
+	    		pageTo("demo_home.html");
+	    	});
+	    		    	
+		</script>	    
+	</head>
+
+<body>
+	<div class="list">
+		<div class="list-header">瀹瑰櫒</div>
+		<div class="list-line" onclick="pageTo('demo_tab')">Tab</div>
+		<div class="list-line" onclick="pageTo('demo_accordion')">Accordion</div>
+		<div class="list-line" onclick="pageTo('demo_portal')">Portal</div>
+		<div class="list-line" onclick="pageTo('demo_secret')">Secret</div>
+		<div class="list-line" onclick="pageTo('demo_flash')">flash</div>
+		
+		<div class="list-header">琛ㄦ牸鍙婃爲褰㈡帶浠�</div>
+		<div class="list-line">Grid</div>
+		<div class="list-line">List</div>
+		<div class="list-line">Tree</div>
+		<div class="list-line">SuperTree</div>
+		
+		<div class="list-header">Form鎺т欢</div>
+		<div class="list-line">Edit</div>
+		<div class="list-line">RadioBox</div>
+		<div class="list-line">CheckBox</div>
+		<div class="list-line">Combobox</div>
+		<div class="list-line">RadioList</div>
+		<div class="list-line">CheckBoxList</div>
+		<div class="list-line">Card</div>
+		
+		<div class="list-header">寮瑰嚭绐椾綋</div>
+		<div class="list-line">Win</div>
+		<div class="list-line">Alert</div>
+		<div class="list-line">Dialog</div>
+		<div class="list-line">Toast</div>
+		<div class="list-line">Loading</div>
+		
+		<div class="list-header">鎸夐挳鎺т欢</div>
+		<div class="list-line">Btn</div>
+		<div class="list-line">BtnList</div>
+		<div class="list-line">BtnBar</div>
+		
+		<div class="list-header"></div>
+	</div>
+
+	<div class="content">
+		<iframe id="demo-content" width="100%" height="100%" style="overflow: hidden; border: none;">
+		
+		</iframe>	
+	</div>
+	
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/demo_container/demo_home.html b/WebRoot/page/demo_container/demo_home.html
new file mode 100644
index 0000000..012f225
--- /dev/null
+++ b/WebRoot/page/demo_container/demo_home.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../../css/demo.css" rel="stylesheet">
+	    
+	    <script type="text/javascript">
+	    
+		</script>	    
+	</head>
+
+<body>
+	<div style="margin-left: 30px; height: 100%;">
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>
+		<div class="card"></div>	
+	</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/demo_container/demo_tab.html b/WebRoot/page/demo_container/demo_tab.html
new file mode 100644
index 0000000..2261c2f
--- /dev/null
+++ b/WebRoot/page/demo_container/demo_tab.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/main.css" rel="stylesheet">
+	    
+	    <script type="text/javascript">
+	    
+		</script>	    
+	</head>
+
+<body>
+	this is API;
+
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/file/fileio.html b/WebRoot/page/file/fileio.html
new file mode 100644
index 0000000..99edb84
--- /dev/null
+++ b/WebRoot/page/file/fileio.html
@@ -0,0 +1,114 @@
+<!DOCTYPE >
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>fileio閰嶇疆</title>
+
+<link rel="stylesheet" href="../../css/tree.css" />
+<link rel="stylesheet" href="../../css/card.css" />
+
+<script type="text/javascript" src="../../js/jquery-1.7.2.min.js" ></script>
+<script type="text/javascript" src="../../js/extend.js" ></script>
+<script type="text/javascript" src="../../js/core.js" ></script>
+<script type="text/javascript" src="../../js/control.js" ></script>
+<script type="text/javascript" src="../../js/tree.js" ></script>
+<script type="text/javascript" src="../../js/card.js" ></script>
+
+<script type="text/javascript">
+	var tree, grid;	
+	var treeData = [
+		{id:3, parentid:3, position:"categrorycode", name:"category3"},
+		{id:2, parentid:2, position:"categrorycode", name:"category2"},
+		{id:1, parentid:1, position:"categrorycode", name:"category1"},
+		{id:31, parentid:3, position:"code", name:"code3"},
+		{id:11, parentid:1, position:"code", name:"code1"},
+		{id:12, parentid:1, position:"code", name:"code12"},
+		{id:21, parentid:2, position:"code", name:"code2"},
+		{id:111, parentid:11, position:"id", name:"A1"},
+		{id:112, parentid:11, position:"id", name:"A2"},
+	];
+	
+	var departmentdatas = [
+		{code: "PMO", name: "PMO"},
+		{code: "OPC", name: "OPC"},
+		{code: "ASD", name: "ASD"},
+		{code: "other", name: "鍏朵粬"}
+	];
+	var captiondatas = [
+		{code: "閮ㄩ棬棰嗗", name: "閮ㄩ棬棰嗗"},
+		{code: "鏅�氱敤鎴�", name: "鏅�氱敤鎴�"},
+		{code: "绯荤粺绠$悊鍛�", name: "绯荤粺绠$悊鍛�"},
+		{code: "other", name: "鍏朵粬"}
+	];	
+	var activedatas = [
+		{code: "T", name: "婵�娲�"},
+		{code: "F", name: "鍐荤粨"},
+	];	
+	var positiondatas = [
+		{code: "VGM", name: "VGM"},
+		{code: "GM", name: "GM"},
+		{code: "admin", name: "绯荤粺绠$悊鍛�"},
+		{code: "ASD", name: "瀹㈡埛鏈嶅姟浜嬩笟閮�"},
+		{code: "PMD1", name: "椤圭洰绠$悊涓�閮�"},
+		{code: "PMD2", name: "椤圭洰绠$悊浜岄儴"},
+		{code: "PMD3", name: "椤圭洰绠$悊涓夐儴"},
+		{code: "PMD4", name: "椤圭洰绠$悊鍥涢儴"},
+		{code: "PMD5", name: "椤圭洰绠$悊浜旈儴"},
+		{code: "PMD6", name: "椤圭洰绠$悊鍏儴"},
+		{code: "PMO1", name: "椤圭洰绠$悊鍔炲叕涓�瀹�"},
+		{code: "PMO2", name: "椤圭洰绠$悊鍔炲叕涓�瀹�"},
+		{code: "PMO", name: "椤圭洰绠$悊鍔炲叕瀹�"},
+		{code: "other", name: "鍏朵粬"}
+	];
+	$(document).ready(function() {
+		tree = new Tree({
+			element: "tree",
+			data: treeData,
+			autoExpended: true,
+			renderNodeText: function(element, record) {
+				element.html(record.position + "--" + record.name);
+			},
+			onNodeSelect: function(node) {
+				
+			}
+		});
+		
+		card = new Card({
+			element: "card",
+			columns: [
+				{field: "fromname", caption: "fromname", type: "text", readonly:true},
+				{field: "fromrowno", caption: "no", type: "text"},
+				{field: "toname", caption: "toname", type: "text"},
+				{field: "torowno", caption: "瀵嗙爜", type: "text"},
+				{field: "XX",caption: "typecode", type: "select"},
+				{field: "XX+",caption: "瑙掕壊:",type: "select"},
+				{field: "XX++",caption: "鐩存姤閮ㄩ棬:",type: "select", datas: positiondatas},
+				{field: "xx+++",caption: "鐩存姤:",type: "select"},
+				{field: "active", caption: "鍐荤粨/婵�娲�",datas: activedatas,type: "select"}
+			]
+		}); 
+	});
+</script>
+
+</head>
+
+<body>
+	<div style="position:absolute; top: 10px; left: 2%; bottom: 10px; border: 0px solid #ddd; width: 25%;">
+		<div  id="tree" style="border: 1px solid #ddd; width: 100%; height: 80%"></div>
+	</div>
+	
+	<div style="position:absolute; top: 10px; left: 29%; right:4%; bottom: 10px;">
+		<div style="position:absolute; border: 1px solid #ddd; width: 100%; height: 10%">
+			<div id="current_data" style="float: left; height: 45%; font-size: 20px; margin-top: 15px">
+				code
+			</div>
+		</div>
+		
+		<div style="position:absolute; width: 100%; height: 90%; top: 10%; border: 1px solid #ddd;">
+			<div id="card" style="text-align: left;"></div>
+		</div>
+	</div>
+	<div style="position: absolute; left: 40%; bottom: 30%; height: 30px; line-height: 30px; margin-top: 15px;" align="center" >
+	</div>	
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/file/filelog.html b/WebRoot/page/file/filelog.html
new file mode 100644
index 0000000..97035f9
--- /dev/null
+++ b/WebRoot/page/file/filelog.html
@@ -0,0 +1,192 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<title>log鏌ョ湅</title>
+	<link href="../../css/commons.css" rel="stylesheet" type="text/css">
+	<link href="../../css/controls.css" rel="stylesheet" />
+	<link href="../../css/grid.css" rel="stylesheet" type="text/css">
+	<script src="../../js/jquery-1.7.2.min.js"></script>
+	<script src="../../js/core.js"></script>
+	<script src="../../js/grid.js"></script>
+	
+	<script type="text/javascript" >
+		var user, grid, filter, param = "";
+		
+		//1.鏌ヨ鏉′欢
+		function clearFilter(){
+			filter.clear();
+		}
+		
+		function query(){
+			param = filter.toFilter();
+			
+			var url = "root/data/customerorgmsg/getSetByPage?pageno=1&pagesize=20&orderby=updatetime desc";
+			grid.setURL(url);
+		}
+		
+		//2.鍗曟嵁鎿嶄綔
+		function newCompany() {
+			var data = grid.getSelected();
+			if(data) {
+				data = data.record;
+			}
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: data,
+				url: "root/page/manager/newcompany.html",
+				callback: saveLine
+			});
+		}
+		
+		function newProject() {
+			var data = grid.getSelected();
+			if(data) {
+				data = data.record;
+			}
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: data,
+				url: "root/page/manager/newproject.html",
+				callback: saveLine
+			});
+		}
+		
+		function saveLine(data)  {
+			if(!data || !data.table) {
+				return;
+			}
+			var tablename = data.table;
+			data.table = null;
+			Server.saveData("root/data/"+ tablename,data,function(result){
+				if(result){
+					window.top.location.href = "manager_index.html?num=2&" + new Date().getTime();
+				}
+			});
+		}
+		
+		function Changetype(element, value) {
+			if ("top" == value) {
+				value = "Top瀹㈡埛";
+			}
+			else if ("potentialingtop" == value) {
+				value = "娼滃姏Top瀹㈡埛";
+			}
+			else if ("nottop" == value) {
+				value = "闈濼OP";
+			}
+			else if ("common" == value) {
+				value = "鏅�氬鎴�";
+			}
+			element.html(value);
+			
+		}
+		
+		function isActive(element, value) {
+			if ("T" == value) {
+				value = "婵�娲�";
+			}
+			else if ("F" == value) {
+				value = "鍐荤粨";
+			}
+			element.html(value);
+		}
+		
+		function changeActive() {
+			var line = grid.getSelected() ? grid.getSelected().record : null;
+			
+			if (!line) {
+				Dialog.alert("璇烽�夋嫨涓�鏉¤褰�");
+				return;
+			}
+			if (!line.id){
+				Dialog.alert("鏈湁鐩稿叧璁板綍");
+				return;
+			}
+			
+			var params = "table=customerorgmsg&field=active&filter=id='" + line.id + "'";
+			if(line.active == "T") {
+				params += "&active=F"
+			}
+			else if(line.active == "F") {
+				params += "&active=T"
+			}
+			Server.call("root/data/procedure/updatetableactive/changecount", params, function(result){
+				if(result.success) {
+					if(result.integer == 1) {
+						window.top.location.href = "manager_index.html?num=2&" + new Date().getTime();
+					}
+				}
+			});
+		}
+		
+		function addcompanyproject() {
+			var line = grid.getSelected() ? grid.getSelected().record : null;
+			if(!line) {
+				alert("璇烽�夋嫨涓�涓叕鍙�");
+				return;
+			}
+			line.opttype = "add";
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: line,
+				url: "root/page/manager/projectList.html",
+				callback: saveLine
+			});
+			
+		}
+		
+		function delcompanyproject() {
+			var line = grid.getSelected() ? grid.getSelected().record : null;
+			if(!line) {
+				alert("璇烽�夋嫨涓�涓叕鍙�");
+				return;
+			}
+			
+			line.opttype = "del";
+			
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: line,
+				url: "root/page/manager/projectList.html",
+				callback: saveLine
+			});
+			
+		}
+		
+		//4.
+		$(document).ready(function() {
+			user = window.top.user;
+			
+			grid = new $.fm.Grid({
+				element: "sheet",
+				showPage:true,
+				limit: 18,
+				columns: [
+					{field: "taskid", caption: "taskid", width: 120},
+					{field: "opttype", caption: "鎿嶄綔绫诲瀷", width: 200},
+					{field: "filetype", caption: "鏂囦欢绫诲瀷", width: 200},
+					{field: "status", caption: "鐘舵��", width: 240, align: "left"},
+					{field: "updatetime", caption: "鎿嶄綔锛堜笅杞� .zip锛�", width: 180},
+					{field: "logurl", caption: "Log鏂囦欢璺緞", width: 150, render: isActive}
+				]
+			});
+			
+			filter = new Filter({
+				element: "query"
+			});
+			
+			query();
+		});
+	</script>	
+</head>
+
+<body style="overflow: hidden;">
+	<div id="sheet" style="margin: 0px 15px"></div>
+	
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/file/filerecord.html b/WebRoot/page/file/filerecord.html
new file mode 100644
index 0000000..5d129f9
--- /dev/null
+++ b/WebRoot/page/file/filerecord.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<title>涓婁紶璁板綍</title>
+	<link href="../../css/commons.css" rel="stylesheet" type="text/css">
+	<link href="../../css/controls.css" rel="stylesheet" />
+	<link href="../../css/grid.css" rel="stylesheet" type="text/css">
+	<script src="../../js/jquery-1.7.2.min.js"></script>
+	<script src="../../js/core.js"></script>
+	<script src="../../js/grid.js"></script>
+	
+	<script type="text/javascript" >
+		var user, grid, filter, param = "";
+		
+		//1.鏌ヨ鏉′欢
+		function clearFilter(){
+			filter.clear();
+		}
+		
+		function query(){
+			param = filter.toFilter();
+			
+			var url = "root/data/customerorgmsg/getSetByPage?pageno=1&pagesize=20&orderby=updatetime desc";
+			grid.setURL(url);
+		}
+		
+		//2.鍗曟嵁鎿嶄綔
+		function newCompany() {
+			var data = grid.getSelected();
+			if(data) {
+				data = data.record;
+			}
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: data,
+				url: "root/page/manager/newcompany.html",
+				callback: saveLine
+			});
+		}
+		
+		function newProject() {
+			var data = grid.getSelected();
+			if(data) {
+				data = data.record;
+			}
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: data,
+				url: "root/page/manager/newproject.html",
+				callback: saveLine
+			});
+		}
+		
+		function saveLine(data)  {
+			if(!data || !data.table) {
+				return;
+			}
+			var tablename = data.table;
+			data.table = null;
+			Server.saveData("root/data/"+ tablename,data,function(result){
+				if(result){
+					window.top.location.href = "manager_index.html?num=2&" + new Date().getTime();
+				}
+			});
+		}
+		
+		function Changetype(element, value) {
+			if ("top" == value) {
+				value = "Top瀹㈡埛";
+			}
+			else if ("potentialingtop" == value) {
+				value = "娼滃姏Top瀹㈡埛";
+			}
+			else if ("nottop" == value) {
+				value = "闈濼OP";
+			}
+			else if ("common" == value) {
+				value = "鏅�氬鎴�";
+			}
+			element.html(value);
+			
+		}
+		
+		function isActive(element, value) {
+			if ("T" == value) {
+				value = "婵�娲�";
+			}
+			else if ("F" == value) {
+				value = "鍐荤粨";
+			}
+			element.html(value);
+		}
+		
+		function changeActive() {
+			var line = grid.getSelected() ? grid.getSelected().record : null;
+			
+			if (!line) {
+				Dialog.alert("璇烽�夋嫨涓�鏉¤褰�");
+				return;
+			}
+			if (!line.id){
+				Dialog.alert("鏈湁鐩稿叧璁板綍");
+				return;
+			}
+			
+			var params = "table=customerorgmsg&field=active&filter=id='" + line.id + "'";
+			if(line.active == "T") {
+				params += "&active=F"
+			}
+			else if(line.active == "F") {
+				params += "&active=T"
+			}
+			Server.call("root/data/procedure/updatetableactive/changecount", params, function(result){
+				if(result.success) {
+					if(result.integer == 1) {
+						window.top.location.href = "manager_index.html?num=2&" + new Date().getTime();
+					}
+				}
+			});
+		}
+		
+		function addcompanyproject() {
+			var line = grid.getSelected() ? grid.getSelected().record : null;
+			if(!line) {
+				alert("璇烽�夋嫨涓�涓叕鍙�");
+				return;
+			}
+			line.opttype = "add";
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: line,
+				url: "root/page/manager/projectList.html",
+				callback: saveLine
+			});
+			
+		}
+		
+		function delcompanyproject() {
+			var line = grid.getSelected() ? grid.getSelected().record : null;
+			if(!line) {
+				alert("璇烽�夋嫨涓�涓叕鍙�");
+				return;
+			}
+			
+			line.opttype = "del";
+			
+			Win.popup({
+				width: 800,
+				height: 500,
+				data: line,
+				url: "root/page/manager/projectList.html",
+				callback: saveLine
+			});
+			
+		}
+		
+		//4.
+		$(document).ready(function() {
+			user = window.top.user;
+			
+			grid = new $.fm.Grid({
+				element: "sheet",
+				showPage:true,
+				limit: 18,
+				columns: [
+					{field: "id", caption: "id", width: 120},
+					{field: "opttype", caption: "鎿嶄綔绫诲瀷", width: 200},
+					{field: "filetype", caption: "鏂囦欢绫诲瀷", width: 200},
+					{field: "uploaduserid", caption: "涓婁紶浜哄憳id", width: 120},
+					{field: "status", caption: "鐘舵��", width: 240, align: "left"},
+					{field: "excellines", caption: "excel鏉℃暟", width: 100,  render: Changetype},
+					{field: "updatetime", caption: "鎿嶄綔鏃堕棿", width: 180},
+					{field: "logurl", caption: "Log鏂囦欢璺緞", width: 150, render: isActive}
+				]
+			});
+			
+			filter = new Filter({
+				element: "query"
+			});
+			
+			query();
+		});
+	</script>	
+</head>
+
+<body style="overflow: hidden;">
+	<div id="sheet" style="margin: 0px 15px"></div>
+	
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/file/upload.html b/WebRoot/page/file/upload.html
new file mode 100644
index 0000000..648919c
--- /dev/null
+++ b/WebRoot/page/file/upload.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ 	<title>Excel涓婅浇</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<meta http-equiv="Pragma" content="no-cache"> 
+	<meta http-equiv="Cache-Control" content="no-cache"> 
+	<meta http-equiv="Expires" content="0">
+	
+	<link href="../../css/loading.css" rel="stylesheet" />
+	<link href="../../css/dialog.css" rel="stylesheet" />
+	
+	<script src="../../js/jquery-1.7.2.min.js"></script>
+	<script src="../../js/core.js"></script>
+	<script src="../../js/control.js"></script>
+	<script src="../../js/loading.js"></script>
+	<script src="../../js/dialog.js"></script>
+	<style>
+		.dropArea {
+			margin-left: 10px;
+			width:600px;
+			border-style: groove;
+		}
+		.taskline {
+                border-bottom: 1px #CCC dashed;
+                height: 28px;
+                width: 800px;
+                font-size: 15px;
+                font-family: 寰蒋闆呴粦;
+                color: #333;
+                margin: 5px 0px 0px 50px;
+		}
+		progress::-webkit-progress-bar { background: #ccc; }
+		progress::-webkit-progress-value  { background: #18bf5c; }
+		progress {
+			margin-left:220px;
+		    display:block;
+		    width:500px;
+		    background:#ccc;
+		}
+		ie {
+		    height:100%;
+		    width:0%;
+		    display:block;
+		    background: #18bf5c;
+		}
+	</style> 
+	       
+	<script type="text/javascript" >
+		var fileSelector, edt_fileName, btn_select; 
+		var lbl_fileSize, lbl_progress, img_progress;
+		var dropArea, logdata, message, timer, progress;
+		var step_0, step_1;
+	
+		function changeProgressValue(val) {
+			$("#progress").value = val;
+		}
+/////////////////////閫夋嫨涓婁紶鏂囦欢//////////////////////	
+		function selectFile() {
+			fileSelector.val("");
+			fileSelector.click();	
+		}		
+
+		function onSelectFile() {
+			var value = fileSelector.val();
+			edt_fileName.val(value);
+
+			var file = fileSelector[0].files[0];
+			var filename = file.name.toLowerCase();
+			if (filename.indexOf('.xlsx') == -1 && filename.indexOf('.xls') == -1) {
+            	alert("鎮ㄩ�夋嫨鐨勪笉鏄疎xcel鏂囦欢锛�");
+                return false;
+            }
+
+			upload(file);	
+		}
+				
+        function upload(file){
+            pos = file.name.lastIndexOf("\\");
+            var filename = file.name.substring(pos + 1);
+            
+            Dialog.confirm("淇℃伅鎻愮ず", "纭畾涓婅浇[" + filename + "]涓殑鏁版嵁锛�", function(result){
+                if (result) {
+                    lbl_fileSize.text(formatFileSize(file.size));
+					
+                    Server.upload("root/file/uploaddata/2017-02-24", file, function(event){
+                        btn_select.attr("disabled", true);
+                        lbl_progress.html(formatFileSize(event.loaded) + "/" + formatFileSize(event.total));
+                        img_progress.css("width", (event.loaded / event.total) * 100 + "%");
+                        
+                        if (event.loaded != event.total) {
+                            step_0.html("姝e湪涓婅浇锛岃绋嶇瓑...");
+                        }
+                        else {
+                            step_0.html("涓婅浇瀹屾垚 .");
+                            step_1.html("姝e湪杩涜鍚庡彴澶勭悊锛岃绋嶇瓑...");
+                        	timer = setInterval(refresh, 2000);
+                        }
+                    },            
+                    function(result){
+                        btn_select.attr("disabled", false);
+                        step_1.html("鍚庡彴澶勭悊瀹屾垚 .");
+                    });
+                }
+            });
+        }
+		
+		//鎵嬪姩鍒锋柊鏃ュ織
+		function refresh(){
+        	Server.call("root/file/showmessages?notDebug=true", function(result) {
+				var msg = result.arraylist;
+				var str = "";
+				for(var i = 0; i < msg.length; i++){
+					str += '<div class="taskline"><div>' + msg[i] + '</div></div>';
+				}
+				message.empty();
+				message.append(str);
+			});
+			
+			if(step_1.text() == "鍚庡彴澶勭悊瀹屾垚 ." && timer != null){
+				clearInterval(timer);
+			}
+        }
+        
+//////////////////////////鎷栨嫿鎿嶄綔////////////////////////////////////
+		function addDragEvent() {
+			
+			dropArea.on("dragover", function(e) {//鎷栨潵鎷栧幓
+				e.preventDefault();		
+			});
+			
+			dropArea.on("dragenter", function(e) {//鎷栨嫿杩涘叆
+				e.preventDefault();
+			    dropArea.html("璇锋斁涓嬫枃浠�");
+			});
+			
+			dropArea.on("dragleave", function(e) {//鎷栨嫿绉诲嚭
+				e.preventDefault();
+				dropArea.html("灏咵xcel鏂囦欢鎷栨斁鍒版澶�");
+			});
+			
+			dropArea.on("drop", function(e) {//鎷栨嫿閲婃斁
+				e.preventDefault();
+				var filelist = e.originalEvent.dataTransfer.files;
+				
+				if (filelist.length == 0) {
+					return false;
+				}
+				
+				if (filelist[0].name.indexOf('.xlsx') == -1 && filelist[0].name.indexOf('.xls') == -1) {
+					alert("鎮ㄦ嫋鐨勪笉鏄疎xcel鏂囦欢锛�");
+					return false;
+				}
+				
+				upload(filelist[0]);
+				dropArea.html("灏咵xcel鏂囦欢鎷栨斁鍒版澶�");
+			}); 	
+		}
+        
+//////////////////////////////////////////////
+		$(document).ready(function() {
+			try {
+				//1.
+				fileSelector = $("#fileSelector");
+				edt_fileName = $("#edt_fileName");
+				btn_select = $("#btn_select");
+							
+				lbl_fileSize = $("#lbl_fileSize");
+				lbl_progress = $("#lbl_progress");	
+				dropArea = $("#dropArea");
+				logdata = $("#logdata");
+				message = $("#message");
+				
+				step_0 = $("#step_0");
+				step_1 = $("#step_1");
+				img_progress = $("#img_progress");
+	
+				//2.
+				addDragEvent();			
+			}
+			finally {
+				Loading.hide();
+			}
+		});		
+	</script>
+</head>
+
+<body style="overflow: hidden;">
+	
+	<div style="margin: 20px; border: 1px #CCC dashed; font-family:寰蒋闆呴粦;font-size:15px">
+		<div style="margin: 0px 0px 0px 20px; width: 100%">
+			<div style="height: 12px; opacity: 0;" >
+				<input type="file" id="fileSelector" size="120" onchange="onSelectFile()" />
+			</div>
+			
+			鏁版嵁鏂囦欢:&nbsp;
+			<input type="text" id="edt_fileName" class="text_large" style="width: 435px;" disabled="disabled"></input>
+			<input id="btn_select" type="button" style="width: 100px; margin: 0px 20px 0px 0px;" value="閫夋嫨" onclick="selectFile()"></input>
+			
+			<span>鏂囦欢澶у皬锛�</span>
+			<span id="lbl_fileSize">0M</span>
+			<span style="margin-left: 20px;">涓婁紶杩涘害锛�</span>
+			<span id="lbl_progress">0M/0M</span>
+		</div>	      
+					
+		<div id="dropArea" class="dropArea" style="height: 120px;" align="center">
+			灏咵xcel鏂囦欢鎷栨斁鍒版澶�
+		</div>
+		<div style="margin: 10px">
+			<div style="float: left; width:200px">褰撳墠浠诲姟:</div>
+			<progress id="progress" value="50" max="100">
+			    <ie id="ie"></ie>
+			</progress>
+		</div>
+		
+		<div style="height: 420px; margin: 0px 10px 20px 10px; font: 16px 寰蒋闆呴粦; border: 1px #CCC solid;" >
+			<div id="logdata" style="margin-left: 20px; margin-top: 20px ">
+				
+				<!-- <div class="taskline">
+                    <div style="float: left; width: 200px;">涓�.&nbsp;涓婅浇鏁版嵁</div>
+                    <div style="float: left; width: 200px;"><label id="step_0"></label></div>
+                    <div style="clear: both;"></div>
+                </div>
+				
+				<div class="taskline">
+                    <div style="float: left; width: 200px;">浜�.&nbsp;鍚庡彴澶勭悊</div>
+                    <div style="float: left; width: 200px;"><label id="step_1"></label></div>
+                    <div style="clear: both;"></div>
+                </div> -->
+				
+				<!--鍔ㄦ�佹棩蹇�-->
+				<div id="message" style="margin-top:20px"></div>
+				
+			</div>
+		</div>
+	</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/home.html b/WebRoot/page/home.html
new file mode 100644
index 0000000..649ed0f
--- /dev/null
+++ b/WebRoot/page/home.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/home.css" rel="stylesheet">
+	    
+	    <script type="text/javascript">
+	    
+		</script>	    
+	</head>
+
+<body>
+	<div class="header">
+		<div class="header-title">Aegis 鍓嶇妗嗘灦</div>
+		<div class="header-subtitle">杞婚噺绾у墠绔鏋讹紝绠�鍗曪紝鍏煎鎬уソ锛屾湇鍔pollo椤圭洰缁�</div>
+		<div align="center" style="margin-top: 30px;">
+			<div class="header-button" style="margin-right: 30px;">寮�鍙戝寘涓嬭浇(v1.0)</div>
+			<div class="header-button">婧愮爜涓嬭浇(v1.0)</div>
+		</div>
+	</div>
+	<div class="article">
+		<p class="article-title">浣跨敤璇存槑锛�</p>
+		<ol>
+			<li class="article-line">涓嬭浇鎺т欢寮�鍙戝寘锛屽苟瑙e帇锛�<a href="">寮�鍙戝寘v1.0涓嬭浇</a>锛�</li>
+			<li class="article-line">灏嗚В鍘嬪悗鐨凧S鏂囦欢鏀惧埌Web椤圭洰鐨刯s鐩綍涓嬮潰</li>
+			<li class="article-line">鏈鏋跺熀浜巎Query锛屽洜姝ゅ湪椤甸潰鏂囦欢涓偍闇�瑕佸厛寮曞叆jQuery搴擄紙<a href="">jQuery v1.7.2涓嬭浇</a>锛�</li>
+			<li class="article-line">鍦ㄩ〉闈㈡牴鎹渶瑕佸紩鐢↗S鏂囦欢锛屽叾涓璫ore.js蹇呴渶寮曠敤鐨勮�屼笖闇�瑕佺涓�涓寮曠敤鐨勬枃浠讹紝鍏朵粬js鏂囦欢鏍规嵁闇�瑕佸紩鐢�</li>
+		</ol>
+	</div>
+	
+	<div style="height: 220px; margin: 15px 100px; border: #c3c3b1 1px solid;">
+		<img alt="娌℃湁鍥剧墖" src="../image/jsfile.png" height="100%" >
+	</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/knowledge.html b/WebRoot/page/knowledge.html
new file mode 100644
index 0000000..3c56493
--- /dev/null
+++ b/WebRoot/page/knowledge.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/main.css" rel="stylesheet">
+	    
+	    <script type="text/javascript">
+	    
+		</script>	    
+	</head>
+
+<body>
+	this is Knowledge;
+
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/main.html b/WebRoot/page/main.html
new file mode 100644
index 0000000..12b1adc
--- /dev/null
+++ b/WebRoot/page/main.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/main.css" rel="stylesheet">
+		<script src="../js/jquery-1.7.2.min.js"></script>
+	    
+	    <script type="text/javascript">
+	    
+	    	function pageTo(target) {
+	    		$("#content").attr("src", "./" + target);
+	    	}
+	    	
+	    	
+	    	$(document).ready(function() {
+	    		pageTo("demo.html");
+	    	});
+	    	
+		</script>	    
+	</head>
+
+<body>
+	<div class="header">
+		<div class="header-button" style="margin-left: 15%;" onclick="pageTo('home.html')">棣栭〉</div>
+		<div class="header-button" onclick="pageTo('demo.html')">鎺т欢Demo</div>
+		<div class="header-button" onclick="pageTo('api.html')">鎺т欢API</div>
+		<div class="header-button" onclick="pageTo('knowledge.html')">妗嗘灦鍘熺悊</div>
+		<div class="header-button" onclick="pageTo('project.html')">椤圭洰鍒楄〃</div>
+	</div>
+
+	<div class="content">
+		<iframe id="content" width="100%" height="100%" style="overflow: hidden; border: none;">
+		
+		</iframe>
+	</div>	
+</body>
+</html>
\ No newline at end of file
diff --git a/WebRoot/page/project.html b/WebRoot/page/project.html
new file mode 100644
index 0000000..05fb8f2
--- /dev/null
+++ b/WebRoot/page/project.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<title>Aegis鍓嶇妗嗘灦</title>
+		<meta charset="utf-8">
+		<meta http-equiv="Pragma" content="no-cache"> 
+		<meta http-equiv="Cache-Control" content="no-cache"> 
+		<meta http-equiv="Expires" content="0">
+		<meta name="viewport" content="user-scalable=no, initial-scale=1, width=device-width, height=device-height">
+		<meta name="format-detection" content="telephone=no">
+		<link href="../css/main.css" rel="stylesheet">
+	    
+	    <script type="text/javascript">
+	    
+		</script>	    
+	</head>
+
+<body>
+	this is Project;
+
+</body>
+</html>
\ No newline at end of file
diff --git a/src/frame/call/writer/EnvelopWriter.java b/src/frame/call/writer/EnvelopWriter.java
new file mode 100644
index 0000000..e857c20
--- /dev/null
+++ b/src/frame/call/writer/EnvelopWriter.java
@@ -0,0 +1,535 @@
+package frame.call.writer;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Stack;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+
+import frame.config.Configer;
+import frame.data.Entity;
+import frame.data.EntitySet;
+import frame.data.reader.EntityReaderContainer;
+import frame.data.reader.IEntityReader;
+import frame.object.http.JsonItem;
+import frame.object.http.ObjectItem;
+import frame.object.http.ResultItem;
+import frame.object.http.ResultPool;
+import frame.util.Util;
+
+public class EnvelopWriter {
+
+	public final static String Code_URL = "url";
+	private final static String NAME_EMPTY = "emptyname";
+
+	protected static Logger logger;
+	protected static EntityReaderContainer objectReaderContainer;
+	private HttpServletResponse response;
+	protected PrintWriter writer; // 鍝嶅簲瀛楃娴�
+	protected OutputStream outputStream; // 鍝嶅簲瀛楄妭娴�
+	private Stack<Boolean> notEmpty;
+	private boolean encode;
+
+	static {
+		logger = Logger.getLogger(EnvelopWriter.class);
+		objectReaderContainer = EntityReaderContainer.getInstance();
+	}
+
+	public EnvelopWriter(HttpServletRequest request, HttpServletResponse response) throws IOException {
+		this.response = response;
+		notEmpty = new Stack<Boolean>();
+		encode = true;
+	}
+
+	public PrintWriter getWriter() {
+		return writer;
+	}
+
+	private void getPrintWriterFromResponse() throws IOException {// 鑾峰彇鎸囧悜娴忚鍣ㄧ殑瀛楃杈撳嚭娴�
+		response.setCharacterEncoding("UTF-8");
+		writer = response.getWriter();
+
+		notEmpty.clear();
+		notEmpty.add(false);
+	}
+
+	public void replay(ResultPool result) throws Exception {
+		List<ResultItem> itemList = result.getItemList();
+
+		getPrintWriterFromResponse();
+
+		if (result.isJson()) {
+			writer.write(result.getJson());
+			return;
+		}
+		
+		writeBegin();
+		try {
+			writeBoolean(IEnvelop.ResultCode_Success, result.isSuccess());
+
+			if (result.isSuccess()) {
+				for (ResultItem item: itemList) {
+					if (item instanceof ObjectItem) {
+						IBeanWriter beanWriter = item.getBeanWriter();
+						writeOneObjectItem(item.getName(), item.getValue(), beanWriter);
+					}
+					else if (item instanceof JsonItem) {
+						writeOneJsonItem(item.getName(), item.getValue());
+					}
+				}
+			}
+			else {
+				writeString(IEnvelop.ResultCode_ErrorCode, result.getErrorCode());
+				writeString(IEnvelop.ResultCode_ErrorMessage, result.getErrorMessage());
+			}
+		}
+		finally {
+			writeEnd();
+		}
+	}
+
+	@SuppressWarnings("rawtypes")
+	private void writeOneObjectItem(String name, Object value, IBeanWriter beanWriter) throws Exception {
+		if (value instanceof IBeanWriter) {
+			writeSmartWriter(name, (IBeanWriter) value);
+		}
+		else if (value instanceof String) {
+			writeString(name, (String) value);// 鍐欏瓧绗︿覆
+		}
+		else if (value instanceof Integer) {
+			writeInteger(name, (Integer) value);// 鍐欐暣鍨�
+		}
+		else if (value instanceof BigDecimal) {
+			writeBigDecimal(name, (BigDecimal) value);// 鍐欏ぇ灏忔暟
+		}
+		else if (value instanceof Date) {
+			writeDate(name, (Date) value);// 鍐欐棩鏈�
+		}
+		else if (value instanceof Boolean) {
+			writeBoolean(name, (Boolean) value);// 鍐檅oolean
+		}
+		else if (value instanceof Entity) {
+			writeEntity(name, (Entity) value);// 鍐欏疄浣�
+		}
+		else if (value instanceof EntitySet) {
+			writeEntitySet(name, (EntitySet) value);// 鍐欏疄浣撻泦
+		}
+		else if (value instanceof Collection) {
+			writeCollection(name, (Collection) value, beanWriter);
+		}
+		else {
+			writeObject(name, value, beanWriter);// 鍐欏璞�
+		}
+	}
+	
+	private void writeOneJsonItem(String name, Object value) throws Exception {
+		writeComma();
+		
+		writeName(name);
+		writer.write((String)value);
+
+		setNotEmpty();
+	}
+
+	private void writeSmartWriter(String name, IBeanWriter smartWriter) {
+		writeComma();
+		writeName(name);
+		
+		smartWriter.write(this);
+		setNotEmpty();
+	}
+	
+	private void writeBegin() {
+		writer.write("{");
+	}
+
+	private void writeEnd() {
+		writer.write("}");
+	}
+
+	public void flush() {
+		if (writer != null) {
+			try {
+				writer.flush();
+				writer.close();
+			}
+			catch (Exception e) {
+				logger.error(e);
+			}
+		}
+
+		if (outputStream != null) {
+			try {
+				outputStream.flush();
+				outputStream.close();
+			}
+			catch (Exception e) {
+				logger.error(e);
+			}
+		}
+	}
+
+	public void write(String value) {
+		writer.write(value);
+	}
+
+	public void writeString(String name, String value) {
+		writeComma();
+		writeName(name);
+
+		writer.write("\"");
+		writer.write(encode(value));
+		writer.write("\"");
+
+		setNotEmpty();
+	}
+	
+	public void writeInteger(String name, Integer value) {
+		writeComma();
+		writeName(name);
+
+		writer.write(String.valueOf(value));
+		setNotEmpty();
+	}
+
+	public void writeBigDecimal(String name, BigDecimal value) {
+		writeComma();
+		writeName(name);
+
+		if (value != null) {
+			writer.write(value.toString());
+		}
+		else {
+			writer.write("null");
+		}
+		
+		setNotEmpty();
+	}
+
+	public void writeDate(String name, Date value) {
+		writeComma();
+		writeName(name);
+
+		if (value == null) {
+			writer.write("null");
+		}
+		else {
+			writer.write("\"");
+			writer.write(Util.DataTimeToString(value));
+			writer.write("\"");
+		}
+
+		setNotEmpty();
+	}
+
+	public void writeBoolean(String name, Boolean value) {
+		writeComma();
+		writeName(name);
+
+		writer.write(value.toString());
+		setNotEmpty();
+	}
+
+	public void writeEntity(String name, Entity entity) {
+		if (entity == null) {
+			return;
+		}
+		
+		if (name == null) {
+			name = IEnvelop.ResultCode_DataLine;
+		}
+
+		writeComma();
+		writeName(name);
+
+		doWriteEntity(entity);
+		setNotEmpty();
+	}
+
+	private void doWriteEntity(Entity entity) {
+		String[] propertyNames = entity.getLowerNames();
+
+		writer.write("{");
+
+		int cnt = propertyNames.length;
+		int i;
+
+		for (i = 0; i < cnt; i++) {
+			if (i > 0) {
+				writer.print(", ");
+			}
+
+			writeName(propertyNames[i]);
+			try {
+				writer.write(entity.getJSONString(i));
+			}
+			catch (Exception e) {
+				writer.write("error");
+			}
+		}
+
+		writer.write("}");
+	}
+
+	public void writeEntitySet(String name, EntitySet entitySet) {
+		if (name == null) {
+			name = IEnvelop.ResultCode_DataSet;
+		}
+		
+		writeComma();
+
+		if (entitySet == null || entitySet.size() == 0) {
+			writer.write("\"count\": 0, ");
+			writeName(name);
+			writer.write("[]");
+			return;
+		}
+
+		int cnt = entitySet.size();
+
+		writer.write("\"count\": " + cnt);
+		writer.write(", ");
+		writeName(name);
+		writer.write("[");
+
+		boolean empty = true;
+
+		for (Entity entity : entitySet) {
+			if (!empty) {
+				writer.write(", ");
+			}
+
+			doWriteEntity(entity);
+
+			empty = false;
+		}
+
+		writer.write("]");
+		setNotEmpty();
+	}
+
+	@SuppressWarnings("rawtypes")
+	private void writeCollection(String name, Collection collection, IBeanWriter beanWriter) throws Exception {
+		writeComma();
+		writeName(name);
+
+		beginArray();
+
+		if (collection.isEmpty()) {
+			endArray();
+			return;
+		}
+
+		for (Object obj : collection) {
+			writeOneObjectItem(NAME_EMPTY, obj, beanWriter);
+		}
+
+		endArray();
+	}
+
+	public void writeObject(String name, IBeanWriter smartWriter) {
+		writeComma();
+		writeName(name);
+
+		beginObject();
+		smartWriter.write(this);
+		endObject();
+
+		setNotEmpty();
+	}
+
+	public void writeObject(String name, Collection<IBeanWriter> smartWriters) {
+		writeComma();
+		writeName(name);
+
+		beginObject();
+
+		for (IBeanWriter smartWriter : smartWriters) {
+			smartWriter.write(this);
+		}
+
+		endObject();
+		setNotEmpty();
+	}
+
+	public void writeArray(String name, Collection<? extends IBeanWriter> smartWriters) {
+		writeComma();
+		writeName(name);
+
+		beginArray();
+
+		for (IBeanWriter smartWriter : smartWriters) {
+			writeComma();
+			smartWriter.write(this);
+			setNotEmpty();
+		}
+
+		endArray();
+		setNotEmpty();
+	}
+
+	public void writeObject(Object object) {
+		writeObject(null, object, null);
+	}
+
+	public void writeObject(String name, Object object, IBeanWriter beanWriter) {
+		try {
+			writeComma();
+			writeName(name);
+			
+			if (beanWriter == null) {
+				IEntityReader entityReader = objectReaderContainer.getEntityReader(object.getClass());
+				writer.write(entityReader.getJSONString(object));
+			}
+			else {
+				beanWriter.setBean(object);
+				beanWriter.write(this);
+			}
+
+			setNotEmpty();
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+			writeString(name, "error");
+		}
+	}
+
+	private String encode(String value) {
+		if (!encode) {
+			return value;
+		}
+		
+		String result = "";
+
+		if (value == null) {
+			return result;
+		}
+
+		try {
+			result = URLEncoder.encode(value, "UTF-8");
+			result = result.replace("+", "%20");
+		}
+		catch (Exception e) {
+			result = value;
+		}
+
+		return result;
+	}
+
+	public void ReplyError(String errorMessage) throws IOException {
+		ReplyError(null, errorMessage);
+	}
+
+	public void ReplyError(String errorCode, String errorMessage) throws IOException {
+		getPrintWriterFromResponse();
+
+		writeBegin();
+		try {
+			writeBoolean(IEnvelop.ResultCode_Success, false);
+
+			if (!Util.isEmptyStr(errorCode)) {
+				writeString(IEnvelop.ResultCode_ErrorCode, errorCode);
+			}
+
+			writeString(IEnvelop.ResultCode_ErrorMessage, errorMessage);
+		}
+		finally {
+			writeEnd();
+		}
+	}
+
+	public void replayTimeout() throws IOException {
+		getPrintWriterFromResponse();
+
+		writeBegin();
+		try {
+			writeBoolean(IEnvelop.ResultCode_Success, false);
+
+			writer.write("\"timeoutPage\": \"" + URLEncoder.encode(Configer.getPage_TimeOut(), "UTF-8") + "\"");
+		}
+		finally {
+			writeEnd();
+		}
+	}
+
+	public void beginObject(String propName) {
+		if (propName == null) {
+			propName = "empty";
+		}
+		
+		propName = propName.toLowerCase();
+		
+		notEmpty.push(false);
+		writer.write("\"" + propName + "\": {");
+	}
+	
+	public void beginObject() {
+		writeComma();
+		
+		notEmpty.push(false);
+		writer.write("{");
+	}
+
+	public void endObject() {
+		notEmpty.pop();
+		writer.write("}");
+		
+		setNotEmpty();
+	}
+
+	public void beginArray() {
+		notEmpty.push(false);
+		writer.write("[");
+	}
+
+	public void endArray() {
+		notEmpty.pop();
+		writer.write("]");
+		
+		setNotEmpty();
+	}
+
+	public void writeComma() {
+		if (notEmpty.peek()) {
+			writer.write(", ");
+		}
+	}
+
+	private void setNotEmpty() {
+		if (notEmpty.peek()) {
+			return;
+		}
+
+		notEmpty.pop();
+		notEmpty.push(true);
+	}
+	
+	private void writeName(String name) {
+		if (name == null) {
+			writer.write("\"empty\": ");
+			return;
+		}
+		
+		if (!NAME_EMPTY.equals(name)) {
+			writer.write("\"" + name.toLowerCase() + "\": ");
+		}	
+	}
+
+	public boolean isEncode() {
+		return encode;
+	}
+
+	public void setEncode(boolean encode) {
+		this.encode = encode;
+	}
+	
+}
diff --git a/src/frame/call/writer/IBeanWriter.java b/src/frame/call/writer/IBeanWriter.java
new file mode 100644
index 0000000..5f26c21
--- /dev/null
+++ b/src/frame/call/writer/IBeanWriter.java
@@ -0,0 +1,10 @@
+package frame.call.writer;
+
+
+public interface IBeanWriter {
+
+	void write(EnvelopWriter writer);
+
+	void setBean(Object object);
+
+}
diff --git a/src/frame/call/writer/IEnvelop.java b/src/frame/call/writer/IEnvelop.java
new file mode 100644
index 0000000..69d711b
--- /dev/null
+++ b/src/frame/call/writer/IEnvelop.java
@@ -0,0 +1,34 @@
+package frame.call.writer;
+
+public interface IEnvelop {
+
+	public final static String ResultCode_Success = "success";
+	public final static String ResultCode_ErrorCode = "errorcode";
+	public final static String ResultCode_ErrorMessage = "errormessage";
+	public final static String ResultCode_Message = "message";
+	
+	public final static String ResultCode_DataLine = "line";
+	public final static String ResultCode_DataSet = "Rows";
+	public final static String ResultCode_TotalCount = "Total";
+	public final static String ResultCode_BarCodeResult = "barcoderesult";	
+	public final static String ResultCode_Tree = "tree";	
+	public final static String ResultCode_Vtable = "vtable";
+	public final static String ResultCode_Value = "value";
+	
+	public final static String ResultCode_Page = "page";
+	public final static String ResultCode_Page_BeginRecordNo = "beginRecordNo";
+	public final static String ResultCode_Page_Size = "size";
+	public final static String ResultCode_Page_EndRecordNo = "endRecordNo";
+	public final static String ResultCode_Page_RecordCount = "recordCount";
+	public final static String ResultCode_Page_PageNo = "pageNo";
+	public final static String ResultCode_Page_PageCount = "pageCount";	
+	
+	public final static String ResultCode_MessageList = "messageList";
+	public final static String ResultCode_StepMessage = "stepMessage";
+	public final static String ResultCode_CurrentPhase = "currentPhase";
+	
+	public final static String Error_Code_Timeout = "timeout";
+	public final static String Error_Code_ServerError = "serverError";
+ 	public final static String Error_Messgae_Timeout = "session timeout";
+ 	public final static String Error_Messgae_ServerError = "server error";
+}
diff --git a/src/frame/call/writer/JsonWriter.java b/src/frame/call/writer/JsonWriter.java
new file mode 100644
index 0000000..4792261
--- /dev/null
+++ b/src/frame/call/writer/JsonWriter.java
@@ -0,0 +1,156 @@
+package frame.call.writer;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+public class JsonWriter {
+	
+    private StringBuilder content;
+    private boolean empty;
+
+    public JsonWriter() {
+        content = new StringBuilder();
+        empty = true;
+    }
+
+    public void beginObject() {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("{");
+        empty = true;
+    }
+
+    public void beginObject(String name) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": {");
+        empty = true;
+    }
+
+    public void endObject() {
+        content.append("}");
+        empty = false;
+    }
+
+    public void beginArray() {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("[");
+        empty = true;
+    }
+
+    public void beginArray(String name) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": [");
+        empty = true;
+    }
+
+    public void endArray() {
+        content.append("]");
+        empty = false;
+    }
+
+    public void addValue(String name, String value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": \"" + value + "\"");
+        empty = false;
+    }
+    
+    public void addValue(String name, int value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": " + value);
+        empty = false;
+    }
+
+    public void addValue(String name, BigDecimal value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": " + value);
+        empty = false;
+    }
+
+    public void addValue(String name, boolean value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": " + (value ? "true" : "false"));
+        empty = false;
+    }
+
+    public void addValue(String name, Date value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + name + "\": \"" + value + "\"");
+        empty = false;
+    }
+
+    public void addValue(String value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + value + "\"");
+        empty = false;
+    }
+    public void addValue(int value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append(value);
+        empty = false;
+    }
+
+    public void addValue(BigDecimal value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append(value);
+        empty = false;
+    }
+
+    public void addValue(boolean value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append(value ? "true" : "false");
+        empty = false;
+    }
+
+    public void addValue(Date value) {
+        if (!empty) {
+            content.append(", ");
+        }
+
+        content.append("\"" + value + "\"");
+        empty = false;
+    }
+
+	@Override
+	public String toString() {
+		return content.toString();
+	}
+    
+}
diff --git a/src/frame/config/Configer.java b/src/frame/config/Configer.java
new file mode 100644
index 0000000..38e58e9
--- /dev/null
+++ b/src/frame/config/Configer.java
@@ -0,0 +1,224 @@
+package frame.config;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import frame.data.DataBaseType;
+import frame.data.DataCell;
+import frame.data.Variant;
+import frame.expression.Expression;
+import frame.expression.VariantContext;
+import frame.expression.VariantRequestParams;
+import frame.util.Util;
+
+
+public class Configer extends VariantContext {
+
+	private static Configer instance;
+	private static Object lock = new Object();
+	
+	private Map<String, String> params;
+	private List<DataCell> clientSysparams;
+	private String DataBase_Schema = null;
+	private String Path_Application;
+	private String Path_WebInfo;
+	private String Path_Config;
+	private String Path_SQL;
+	private DataBaseType dataBaseType;
+
+	private Configer() {
+		
+	}
+	
+	public static Configer getInstance() {
+		if (instance == null) {
+			synchronized (lock) {
+				if (instance == null) {
+					instance = new Configer();
+				}
+			}
+		}
+		
+		return instance;
+	}
+	
+	public static void init(ServletContext servletContext) {
+		getInstance();
+		
+		instance.params = new HashMap<String, String>();
+		instance.clientSysparams = new ArrayList<DataCell>();
+
+		instance.Path_Application = servletContext.getRealPath("").replace("\\", "/");
+		instance.Path_WebInfo = servletContext.getRealPath("/WEB-INF").replace("\\", "/");
+		instance.Path_Config = instance.Path_WebInfo + "/config/";
+		instance.Path_SQL = instance.Path_WebInfo + "/sql/";
+	}
+
+	public static void afterLoadParams() {
+		String typeString = getParam("dataBaseType");
+		instance.dataBaseType = DataBaseType.valueOfString(typeString);
+	}
+
+	public static void addParam(String name, String value, boolean client) throws Exception {
+		Expression expression = new Expression(value);
+		
+		if (!expression.isVariantEmpty()) {
+			instance.setParametersTo(expression);
+			value = expression.getString();
+		}
+		
+		instance.params.put(name.toLowerCase(), value);
+		
+		if (client) {
+			instance.clientSysparams.add(new DataCell(name, new Variant(value)));
+		}
+	}
+	
+	@Override
+	public String getStringValue(String variantName, VariantRequestParams requestParams) {
+		if (variantName == null) {
+			return null;
+		}
+		
+		if ("path_application".equalsIgnoreCase(variantName)) {
+			return Path_Application;
+		}
+		else if ("path_config".equalsIgnoreCase(variantName)) {
+			return Path_Config;
+		}
+		else if ("path_sql".equalsIgnoreCase(variantName)) {
+			return Path_SQL;
+		}
+		else if ("path_webinfo".equalsIgnoreCase(variantName)) {
+			return Path_WebInfo;
+		}
+		else {
+			return params.get(variantName.toLowerCase());
+		}
+	}
+
+	public static String getParam(String name) {
+		if (name == null) {
+			return null;
+		}
+
+		return instance.params.get(name.toLowerCase());
+	}
+
+	public static String getPath_WebInfo() {
+		return instance.Path_WebInfo;
+	}
+
+	public static String getPath_Config() {
+		return instance.Path_Config;
+	}
+
+	public static String getPath_TimerConfig() {
+		return instance.Path_Config + "timer.properties";
+	}
+
+	public static String getWebserviceURI() {
+		return "http://www.jydatas.com/";
+	}
+
+	public static String getPath_Application() {
+		return instance.Path_Application;
+	}
+	
+	public static String getPath_Application(String subpath) {
+		if (subpath == null) {
+			return instance.Path_Application;
+		}
+		
+		subpath = subpath.replace("\\", "/");
+		
+		if ('/' != subpath.charAt(0)) {
+			subpath = "/" + subpath;
+		}
+		
+		if ('/' != subpath.charAt(subpath.length() - 1)) {
+			subpath = subpath + "/";
+		}
+		
+		return instance.Path_Application + subpath;
+	}
+
+	public static String getPath_LoggerConfig() {
+		return instance.Path_Config + "log4j.properties";
+	}
+
+	public static String getPath_ActivePeriodConfig() {
+		return instance.Path_Config + "activeperiod.properties";
+	}
+
+	public static String getPath_SQLConfig() {
+		return instance.Path_SQL;
+	}
+
+	public static String getPath_SQLDTD() {
+		return instance.Path_Config + "sql.dtd";
+	}
+
+	public static String getPath_MainConfig() {
+		return instance.Path_Config + "config.xml";
+	}
+
+	public static String getPath_Datasource() {
+		return instance.Path_Config + "datasource.xml";
+	}
+
+	public static String getPath_Upload(String username) {
+		return instance.Path_Application + "/upload/" + username;
+	}
+
+	public static String getPath_Temp() {
+		return instance.Path_Application + "/temp";
+	}
+	
+	public static String getPath_Temp(String username) {
+		return instance.Path_Application + "/temp/" + username;
+	}	
+
+	public static String getPath_WXConfig() {
+		return instance.Path_Config + "weixin.properties";
+	}
+
+	public static List<DataCell> getClientSysparams() {
+		return instance.clientSysparams;
+	}
+
+	// ***************Page******************//
+	public static String getPage_TimeOut() {
+		String appName = getParam("appName");
+		String timeOutPage = getParam("timeOutPage");
+
+		return "/" + appName + "/" + timeOutPage;
+	}
+
+	public static DataBaseType getDataBaseType() {
+		return instance.dataBaseType;
+	}
+
+	public static String getPath_ImageLib(String typeCode) {
+		return instance.Path_Application + "/imagelib/" + typeCode + "/" + Util.newDateTimeStr("yyyyMM") + "/";
+	}
+
+	public static boolean isMultiplyDatasoure() {
+		String lowerCase = "multipleDataSource".toLowerCase();
+		String multi = instance.params.get(lowerCase);
+		return Util.stringToBoolean(multi);
+	}
+
+	public static String getDataBase_Schema() {
+		return instance.DataBase_Schema;
+	}
+
+	public static void setDataBase_Schema(String dataBase_Schema) {
+		instance.DataBase_Schema = dataBase_Schema;
+	}
+
+}
diff --git a/src/frame/config/ContextConfigerLoader.java b/src/frame/config/ContextConfigerLoader.java
new file mode 100644
index 0000000..7d2b9f5
--- /dev/null
+++ b/src/frame/config/ContextConfigerLoader.java
@@ -0,0 +1,311 @@
+package frame.config;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.xml.sax.EntityResolver;
+
+import frame.role.UserRightContainer;
+
+
+public class ContextConfigerLoader {
+
+	protected static Logger logger;
+	private static ContextConfigerLoader instance;
+	private static LoaderContainer configLoaderContainer;
+	private static UserRightContainer userRightContainer;
+	private List<VirtualPathConfig> virtualPathList;
+	private List<CallableConfig> callablList;
+
+	static {
+		logger = Logger.getLogger(ContextConfigerLoader.class);
+		configLoaderContainer = LoaderContainer.getInstance();
+		userRightContainer = UserRightContainer.getInstance();
+	}
+
+	private ContextConfigerLoader() {
+		virtualPathList = new ArrayList<VirtualPathConfig>();
+		callablList = new ArrayList<CallableConfig>();
+	}
+
+	public synchronized static ContextConfigerLoader getInstance() {
+		if (instance == null) {
+			instance = new ContextConfigerLoader();
+		}
+
+		return instance;
+	}
+
+	public void load() {
+		String path = Configer.getPath_MainConfig();
+		File file = new File(path);
+
+		loadOneFile(file);
+	}
+
+	private void loadOneFile(File file) {
+		try {
+			logger.debug("load dispatch file:" + file);
+			InputStream inputStream = new FileInputStream(file);
+
+			try {
+				SAXReader reader = new SAXReader();
+				reader.setValidation(false);
+
+				Document doc = reader.read(inputStream);
+				Element root = doc.getRootElement();
+
+				loadParams(root);
+				loadConfigLoader(root);
+				loadFreeVisit(root);
+				loadLimitedVisit(root);
+				loadVirtualPathConfig(root);
+				loadCallableConfig(root);
+				loadDataRight(root);
+			} 
+			catch (DocumentException e) {
+				logger.error("can not load dispatch file: " + file);
+				logger.error(e);
+			} finally {
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+				}
+			}
+		} catch (Exception e) {
+			logger.error(e);
+		}
+	}
+	
+	public void loadClasses() throws Exception {
+		//1.
+		for (VirtualPathConfig virtualPath: virtualPathList) {
+			loadOneVirtualPath(virtualPath);
+		}
+		
+		//2.
+		for (CallableConfig callableConfig: callablList) {
+			loadOneDispatch(callableConfig);
+		}
+	}
+
+	private void loadParams(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator(Node_Param);
+
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+
+			String name = element.attributeValue(Node_Param_Name);
+			String value = element.attributeValue(Node_Param_Value);
+			boolean client = Util.stringToBoolean(element.attributeValue(Node_Param_Client));
+
+			Configer.addParam(name, value, client);
+		}
+
+		Configer.afterLoadParams();
+	}
+
+	private void loadFreeVisit(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator(Node_FreeVisit);
+
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+
+			Iterator<?> typeIterator = element.elementIterator(Node_Type);
+			while (typeIterator.hasNext()) {
+				Element elemnet = (Element) typeIterator.next();
+				String type = elemnet.getTextTrim();
+				loadOneFreeVisitType(type);
+			}
+
+			Iterator<?> resourceIterator = element.elementIterator(Node_Resource);
+			while (resourceIterator.hasNext()) {
+				Element elemnet = (Element) resourceIterator.next();
+				String resource = elemnet.getTextTrim();
+				loadOneFreeVisitResource(resource);
+			}
+
+			Iterator<?> callIterator = element.elementIterator(Node_Call);
+			while (callIterator.hasNext()) {
+				Element elemnet = (Element) callIterator.next();
+				String call = elemnet.getTextTrim();
+				loadOneFreeVisitCall(call);
+			}
+			
+			Iterator<?> excludeIterator = element.elementIterator(Node_Exclude);
+			while (excludeIterator.hasNext()) {
+				Element elemnet = (Element) excludeIterator.next();
+				String exclude = elemnet.getTextTrim();
+				loadOneExcludeResource(exclude);
+			}
+		}
+	}
+	
+	private void loadLimitedVisit(Element root) {
+		Iterator<?> iterator = root.elementIterator(Node_LimitedVisit);
+
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+
+			Iterator<?> typeIterator = element.elementIterator(Node_RoleResource);
+			while (typeIterator.hasNext()) {
+				Element elemnet = (Element) typeIterator.next();
+				String role = elemnet.attributeValue(Node_RoleResource_Role);
+				String resource = elemnet.attributeValue(Node_RoleResource_Resource);
+				userRightContainer.addRoleResource(role, resource);
+			}
+		}
+	}
+
+	private void loadVirtualPathConfig(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator("virtualPaths");
+
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+
+			Iterator<?> mappingIterator = element.elementIterator("virtualPath");
+			while (mappingIterator.hasNext()) {
+				Element elemnet = (Element) mappingIterator.next();
+
+				String path = elemnet.attributeValue("path");
+				String target = elemnet.attributeValue("target");
+				String className = elemnet.attributeValue("classname");
+
+				VirtualPathConfig virtualPath = new VirtualPathConfig(path, target, className);
+				virtualPathList.add(virtualPath);
+			}
+		}
+	}
+
+	private void loadCallableConfig(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator(Node_Callable);
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+
+			Iterator<?> mappingIterator = element.elementIterator(Node_Mapping);
+			while (mappingIterator.hasNext()) {
+				Element elemnet = (Element) mappingIterator.next();
+
+				String path = elemnet.attributeValue(Node_Mapping_Path);
+				String classname = elemnet.attributeValue(Node_Mapping_ClassName);
+
+				CallableConfig callableConfig = new CallableConfig(path, classname);
+				callablList.add(callableConfig);
+			}
+		}
+	}
+
+	private void loadConfigLoader(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator(Node_ConfigLoader);
+
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+			Iterator<?> configIterator = element.elementIterator(Node_ConfigLoader_Loader);
+
+			while (configIterator.hasNext()) {
+				Element loaderEl = (Element) configIterator.next();
+
+				String name = loaderEl.attributeValue(Node_ConfigLoader_Loader_Name);
+				String active = loaderEl.attributeValue(Node_ConfigLoader_Loader_Active);
+				String classname = loaderEl.attributeValue(Node_ConfigLoader_Loader_ClassName);
+				Class<?> clazz = Class.forName(classname);
+
+				ILoader configLoader;
+				Method getInstance = null;
+				try {
+					getInstance = clazz.getDeclaredMethod("getInstance");
+				} catch (NoSuchMethodException e) {
+				}
+
+				if (getInstance != null) {
+					configLoader = (ILoader) getInstance.invoke(null);
+				} else {
+					configLoader = (ILoader) clazz.newInstance();
+				}
+
+				configLoader.setName(name);
+				configLoader.setActive(Util.stringToBoolean(active));
+
+				configLoaderContainer.add(configLoader);
+			}
+		}
+	}
+
+	private void loadDataRight(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator(Node_DataFilter);
+
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();
+			Iterator<?> filterIterator = element.elementIterator(Node_DataFilter_Filter);
+
+			while (filterIterator.hasNext()) {
+				Element filterEl = (Element) filterIterator.next();
+
+				String tablename = filterEl.attributeValue(Node_DataFilter_Filter_TableName);
+				String where = filterEl.attributeValue(Node_DataFilter_Filter_Where);
+
+				userRightContainer.addDataRight(tablename, where);
+			}
+		}
+	}
+
+	private void loadOneFreeVisitType(String type) {
+		if (Util.isEmptyStr(type)) {
+			return;
+		}
+
+		mainDispatcher.appendFreeVisitType(type);
+	}
+
+	private void loadOneFreeVisitResource(String resource) {
+		if (Util.isEmptyStr(resource)) {
+			return;
+		}
+
+		mainDispatcher.appendFreeVisitResource(resource);
+	}
+
+	private void loadOneFreeVisitCall(String call) {
+		if (Util.isEmptyStr(call)) {
+			return;
+		}
+
+		mainDispatcher.appendFreeVisitCalls(call);
+	}
+	
+	private void loadOneExcludeResource(String exclude) {
+		if (Util.isEmptyStr(exclude)) {
+			return;
+		}
+
+		mainDispatcher.appendExcludeResources(exclude);
+	}
+	
+	private void loadOneVirtualPath(VirtualPathConfig virtualPath) throws Exception {
+		if (virtualPath.invalid()) {
+			return;
+		}
+
+		mainDispatcher.appendVirtualPaths(virtualPath.getPath(), virtualPath.getTarget(), virtualPath.getClassName());
+	}
+
+	private void loadOneDispatch(CallableConfig callableConfig) throws Exception {
+		if (callableConfig.invalid()) {
+			return;
+		}
+
+		mainDispatcher.appendCallableClass(callableConfig.getPath(), callableConfig.getClassName());
+	}
+
+}
diff --git a/src/frame/config/ILoader.java b/src/frame/config/ILoader.java
new file mode 100644
index 0000000..6c5b454
--- /dev/null
+++ b/src/frame/config/ILoader.java
@@ -0,0 +1,15 @@
+package frame.config;
+
+public interface ILoader {
+
+	void setActive(boolean active);
+	
+	void setName(String name);
+	
+	boolean isActive();
+
+	String getName();
+	
+	void load() throws Exception;
+	
+}
diff --git a/src/frame/config/Loader.java b/src/frame/config/Loader.java
new file mode 100644
index 0000000..8627880
--- /dev/null
+++ b/src/frame/config/Loader.java
@@ -0,0 +1,48 @@
+package frame.config;
+
+import org.apache.log4j.Logger;
+
+
+public abstract class Loader implements ILoader {
+
+	protected static Logger logger;
+	protected String name;
+	protected boolean active;
+	protected String path;
+	
+	static {
+		logger = Logger.getLogger(Loader.class);		
+	}
+	
+	public Loader() {
+		
+	}
+
+	public abstract void load() throws Exception;
+	
+	public String getName() {
+		return name;
+	}
+
+	public boolean isActive() {
+		return active;
+	}
+
+	public void setActive(boolean active) {
+		this.active = active;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getPath() {
+		return path;
+	}
+	
+	@Override
+	public String toString() {
+		return "[" + name + "]: " + path;
+	}
+
+}
diff --git a/src/frame/config/LoaderContainer.java b/src/frame/config/LoaderContainer.java
new file mode 100644
index 0000000..1c1be22
--- /dev/null
+++ b/src/frame/config/LoaderContainer.java
@@ -0,0 +1,33 @@
+package frame.config;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class LoaderContainer implements Iterable<ILoader>{
+
+	private static LoaderContainer instance;
+	private List<ILoader> itemList;
+	
+	public synchronized static LoaderContainer getInstance() {
+		if (instance == null) {
+			instance = new LoaderContainer();
+		}
+		
+		return instance;
+	}
+	
+	public LoaderContainer() {
+		itemList = new ArrayList<ILoader>();
+	}
+
+	@Override
+	public Iterator<ILoader> iterator() {
+		return itemList.iterator();
+	}
+
+	public void add(ILoader configLoader) {
+		itemList.add(configLoader);
+	}
+
+}
diff --git a/src/frame/data/DataBaseType.java b/src/frame/data/DataBaseType.java
new file mode 100644
index 0000000..970e164
--- /dev/null
+++ b/src/frame/data/DataBaseType.java
@@ -0,0 +1,29 @@
+package frame.data;
+
+public enum DataBaseType {
+
+	Oracle, SQLServer, MySQL, Unknown;
+
+	public static DataBaseType valueOfString(String value) {
+		if (value == null) {
+			return Unknown;
+		}
+		
+		if ("Oracle".equalsIgnoreCase(value)) {
+			return Oracle;
+		}
+		
+		if ("SQLServer".equalsIgnoreCase(value)) {
+			return SQLServer;
+		}
+		
+		if ("MySQL".equalsIgnoreCase(value)) {
+			return MySQL;
+		}
+		
+		return Unknown;
+		
+	}
+	
+	
+}
diff --git a/src/frame/data/DataCell.java b/src/frame/data/DataCell.java
new file mode 100644
index 0000000..3613eff
--- /dev/null
+++ b/src/frame/data/DataCell.java
@@ -0,0 +1,21 @@
+package frame.data;
+
+public class DataCell {
+
+	private String name;
+	private Variant value;
+	
+	public DataCell(String name, Variant value) {
+		this.name = name;
+		this.value = value;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public Variant getValue() {
+		return value;
+	}
+	
+}
diff --git a/src/frame/data/DataContext.java b/src/frame/data/DataContext.java
new file mode 100644
index 0000000..f667db3
--- /dev/null
+++ b/src/frame/data/DataContext.java
@@ -0,0 +1,39 @@
+package frame.data;
+
+public class DataContext {
+	private String tablename;
+    private String filter;
+    private String orderby;
+	
+    public DataContext(String tablename, String filter, String orderby) {
+		super();
+		this.tablename = tablename;
+		this.filter = filter;
+		this.orderby = orderby;
+	}
+    
+	public String getTablename() {
+		return tablename;
+	}
+	
+	public void setTablename(String tablename) {
+		this.tablename = tablename;
+	}
+	
+	public String getFilter() {
+		return filter;
+	}
+	
+	public void setFilter(String filter) {
+		this.filter = filter;
+	}
+	
+	public String getOrderby() {
+		return orderby;
+	}
+	
+	public void setOrderby(String orderby) {
+		this.orderby = orderby;
+	}
+
+}
diff --git a/src/frame/data/DataLink.java b/src/frame/data/DataLink.java
new file mode 100644
index 0000000..f831bfd
--- /dev/null
+++ b/src/frame/data/DataLink.java
@@ -0,0 +1,80 @@
+package frame.data;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class DataLink {
+
+	public static void moveOnConsumer(IDataProvider provider, IDataConsumer consumer) {
+		List<String> nameList = consumer.getDataNameList();
+		
+		for (String name: nameList) {
+			if (provider.containsData(name)) {
+				Object value = provider.getDataValue(name);
+				consumer.setDataValue(name, value);
+			}
+		}
+	}
+	
+	public static boolean moveOnConsumer(IDataProvider provider, IDataConsumer consumer, Set<String> excludeNames) {
+		boolean excluded = false;
+		
+		Set<String> lowerSet = new HashSet<String>();
+		for (String one: excludeNames) {
+			lowerSet.add(one.toLowerCase());
+		}
+		
+		List<String> nameList = consumer.getDataNameList();
+		
+		for (String name: nameList) {
+			if (lowerSet.contains(name)) {
+				excluded = true;
+				continue;
+			}
+			
+			if (provider.containsData(name)) {
+				Object value = provider.getDataValue(name);
+				consumer.setDataValue(name, value);
+			}
+		}		
+		
+		return excluded;
+	}
+	
+	public static void moveOnProvider(IDataProvider provider, IDataConsumer consumer) {
+		List<String> nameList = provider.getDataNameList();
+		
+		for (String name: nameList) {
+			if (consumer.containsData(name)) {
+				Object value = provider.getDataValue(name);
+				consumer.setDataValue(name, value);
+			}
+		}
+	}
+	
+	public static boolean moveOnProvider(IDataProvider provider, IDataConsumer consumer, Set<String> excludeNames) {
+		boolean excluded = false;
+		
+		Set<String> lowerSet = new HashSet<String>();
+		for (String one: excludeNames) {
+			lowerSet.add(one.toLowerCase());
+		}
+		
+		List<String> nameList = provider.getDataNameList();
+		
+		for (String name: nameList) {
+			if (lowerSet.contains(name)) {
+				excluded = true;
+				continue;
+			}
+			
+			if (consumer.containsData(name)) {
+				Object value = provider.getDataValue(name);
+				consumer.setDataValue(name, value);
+			}
+		}		
+		
+		return excluded;
+	}
+}
diff --git a/src/frame/data/DataPool.java b/src/frame/data/DataPool.java
new file mode 100644
index 0000000..7c79b8c
--- /dev/null
+++ b/src/frame/data/DataPool.java
@@ -0,0 +1,118 @@
+package frame.data;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import frame.object.data.IFilterSegmentProvider;
+
+public class DataPool implements Iterable<DataCell>, IDataProvider, IFilterSegmentProvider {
+
+	private Map<String, Variant> valueMap;
+	private List<DataCell> cellList;
+	private List<String> lowerNameList;
+
+	public DataPool() throws Exception {
+		valueMap = new HashMap<String, Variant>();
+		cellList = new ArrayList<DataCell>();
+		lowerNameList = new ArrayList<String>();
+	}
+	
+	public void clear() {
+		valueMap.clear();
+		cellList.clear();
+		lowerNameList.clear();
+	}
+	
+	public void add(String name, Variant value) { 
+		if (name == null) {
+			return;
+		}
+		
+		//1.
+		name = name.toLowerCase();
+		valueMap.put(name, value);
+		
+		//2.
+		DataCell cell = new DataCell(name, value);
+		cellList.add(cell);
+		
+		//3.
+		lowerNameList.add(name);
+	}
+
+	public void add(String name, String value) {
+		Variant variant = new Variant(value);
+		add(name, variant);
+	}
+
+	public Variant getVariant(String name) {
+		if (name == null) {
+			return new Variant();
+		}
+
+		name = name.toLowerCase();
+		Variant variant = valueMap.get(name);
+
+		if (variant == null) {
+			variant = new Variant();
+		}
+
+		return variant;
+	}
+	
+	public String getString(String name) {
+		Variant variant = getVariant(name);
+		return variant.getStringValue();
+	}
+
+	public int getInt(String name, int defaultValue) {
+		Variant variant = getVariant(name);
+		return variant.getIntValue(defaultValue);
+	}
+
+	@Override
+	public String getFilterValue() {
+		return getString("filter");
+	}
+	
+	@Override
+	public Iterator<DataCell> iterator() {
+		return cellList.iterator();
+	}
+
+	@Override
+	public List<String> getDataNameList() {
+		return lowerNameList;
+	}
+
+	@Override
+	public boolean containsData(String name) {
+		if (name == null) {
+			return false;
+		}
+		
+		name = name.toLowerCase();
+		
+		return valueMap.containsKey(name);
+	}
+
+	@Override
+	public Object getDataValue(String name) {
+		if (name == null) {
+			return null;
+		}
+		
+		name = name.toLowerCase();
+		
+		Variant variant = valueMap.get(name);
+		
+		if (variant == null) {
+			return null;
+		}
+		
+		return variant.getValue();
+	}
+}
diff --git a/src/frame/data/DataType.java b/src/frame/data/DataType.java
new file mode 100644
index 0000000..fd23a10
--- /dev/null
+++ b/src/frame/data/DataType.java
@@ -0,0 +1,195 @@
+package frame.data;
+
+import java.sql.Types;
+
+
+public enum DataType {  
+
+	Void, Int, Double, Decimal, Date, String, Boolean, Entity, EntitySet;
+
+	public static DataType valueOfTypes(int value) {
+		if (Types.BIGINT == value) {
+			return Int;
+		}
+		else if (Types.SMALLINT == value) {
+			return Int;
+		}
+		else if (Types.TINYINT == value) {
+			return Int;
+		}
+		else if (Types.INTEGER == value) {
+			return Int;
+		}
+		else if (Types.DECIMAL == value) {
+			return Decimal;
+		}
+		else if (Types.NUMERIC == value) {
+			return Decimal;
+		}	
+		else if (Types.DOUBLE == value) {
+			return Double;
+		}
+		else if (Types.FLOAT == value) {
+			return Double;
+		}
+		else if (Types.DATE == value) {
+			return Date;
+		}	
+		else if (Types.TIME == value) {
+			return Date;
+		}	
+		else if (Types.TIMESTAMP == value) {
+			return Date;
+		}	
+		else if (Types.BOOLEAN == value) {
+			return Boolean;
+		}		
+		else if (Types.BIT == value) {
+			return Boolean;
+		}
+		else {
+			return String;
+		}
+	}
+
+	public static DataType valueOfString(String value) {
+		if (value == null) {
+			return String;
+		}
+		
+		value = value.toLowerCase();
+		
+		if ("string".equals(value)) {
+			return String;
+		}
+		else if ("char".equals(value)) {
+			return String;
+		}
+		else if ("varchar".equals(value)) {
+			return String;
+		}
+		else if ("vchar".equals(value)) {
+			return String;
+		}
+		else if ("text".equals(value)) {
+			return String;
+		}
+		else if ("int".equals(value)) {
+			return Int;
+		}
+		else if ("tinyint".equals(value)) {
+			return Int;
+		}
+		else if ("smallint".equals(value)) {
+			return Int;
+		}
+		else if ("bigint".equals(value)) {
+			return Int;
+		}
+		else if ("long".equals(value)) {
+			return Int;
+		}
+		else if ("number".equals(value)) {
+			return Double;
+		}
+		else if ("decimal".equals(value)) {
+			return Double;
+		}
+		else if ("float".equals(value)) {
+			return Double;
+		}
+		else if ("double".equals(value)) {
+			return Double;
+		}
+		else if ("date".equals(value)) {
+			return Date;
+		}
+		else if ("time".equals(value)) {
+			return Date;
+		}
+		else if ("datetime".equals(value)) {
+			return Date;
+		}
+		else if ("boolean".equals(value)) {
+			return Boolean;
+		}
+		else {
+			return String;
+		}
+	}
+	
+	public String toJavaScriptType() {
+		int no = ordinal();
+
+		if (no == 0) {
+			return "string";
+		}
+		else if (no == 1) {
+			return "integer";
+		}
+		else if (no == 2) {
+			return "double";
+		}
+		else if (no == 3) {
+			return "date";
+		}
+		else if (no == 4) {
+			return "boolean";
+		}
+
+		return "string";
+	}
+
+	public static DataType valueOfSAPTypes(String type) {
+		if (type == null) {
+			return String;
+		}
+		
+		type = type.trim().toLowerCase();
+		
+		if ("c".equalsIgnoreCase(type)) {
+			return String;
+		}
+		else if ("n".equalsIgnoreCase(type)) {
+			return String;
+		}
+		else if ("t".equalsIgnoreCase(type)) {
+			return String;
+		}	
+		else if ("d".equalsIgnoreCase(type)) {
+			return String;
+		}
+		else if ("i".equalsIgnoreCase(type)) {
+			return Int;
+		}
+		else if ("f".equalsIgnoreCase(type)) {
+			return Double;
+		}
+		else if ("p".equalsIgnoreCase(type)) {
+			return Double;
+		}
+		else if ("x".equalsIgnoreCase(type)) {
+			return String;
+		}
+		
+		return String;
+	}
+
+	public int toSQLTypes() {
+		if (Int == this) {
+			return Types.INTEGER;
+		}
+		else if (Double == this) {
+			return Types.NUMERIC;
+		}	
+		else if (Date == this) {
+			return Types.DATE;
+		}	
+		else if (Boolean == this) {
+			return Types.BIT;
+		}		
+		else {
+			return Types.VARCHAR;
+		}
+	}
+}
diff --git a/src/frame/data/Entity.java b/src/frame/data/Entity.java
new file mode 100644
index 0000000..dd1ec8d
--- /dev/null
+++ b/src/frame/data/Entity.java
@@ -0,0 +1,332 @@
+package frame.data;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import frame.data.convert.Convertor;
+import frame.data.meta.EntityMeta;
+import frame.data.meta.MetaContainer;
+import frame.object.data.Filter;
+import frame.object.data.Id;
+import frame.persist.NamedSQL;
+import frame.persist.SQLRunner;
+import frame.util.Util;
+
+
+public class Entity implements IDataConsumer, IDataProvider {
+
+	private EntityMeta entityMeta;
+	private Object[] dataArray;
+
+	
+	public Entity(EntityMeta tableMeta) {
+		this.entityMeta = tableMeta;
+		dataArray = new Object[tableMeta.getFieldCount()];
+	}
+
+	public Entity(String dataName) throws Exception {
+		EntityMeta tableMeta = MetaContainer.get(dataName);
+
+		if (tableMeta == null) {
+			throw new Exception("table not exists: " + dataName);
+		}
+
+		this.entityMeta = tableMeta;
+		dataArray = new Object[tableMeta.getFieldCount()];
+	}
+
+	public void set(int i, Object object) {
+		dataArray[i] = object;
+	}
+
+	public void set(String name, Object object) {
+		entityMeta.setObject(dataArray, name, object);
+	}
+
+	public void setString(String name, String value) throws ParseException {
+		entityMeta.setString(dataArray, name, value);
+	}
+
+	public Object getValue(String fieldName) {
+		int idx = entityMeta.getIndex(fieldName);
+		return dataArray[idx];
+	}
+	
+	public Object getValue(int idx) {
+		return dataArray[idx];
+	}
+
+	public String getString(String fieldName) {
+		int idx = entityMeta.getIndex(fieldName);
+		return getString(idx, null);
+	}
+
+	public String getString(String fieldName, String defaultValue) {
+		int idx = entityMeta.getIndex(fieldName);
+		return getString(idx, defaultValue);
+	}
+
+	public String getString(int idx, String defaultValue) {
+		try {
+			Object value = dataArray[idx];
+			Convertor convertor = entityMeta.getConvertor(idx);
+			return convertor.toString(value);
+		}
+		catch (Exception e) {
+			return "error";
+		}
+	}
+	
+	public String getQuotedString(String fieldName) {
+		int idx = entityMeta.getIndex(fieldName);
+		return getQuotedString(idx, null);
+	}
+
+	public String getQuotedString(String fieldName, String defaultValue) {
+		int idx = entityMeta.getIndex(fieldName);
+		return getQuotedString(idx, defaultValue);
+	}
+	
+	public String getQuotedString(int idx, String defaultValue) {
+		String result = getString(idx, defaultValue);
+		return Util.quotedStr(result);
+	}
+	
+	public String getJSONString(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getJSONString(idx);
+	}
+	
+	public String getJSONString(int idx) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toJSONString(value);
+	}
+
+	public String getSQLString(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getSQLString(idx);
+	}
+	
+	public String getSQLString(int idx) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toSqlString(value);
+	}
+
+	public String getSchemaString(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getSchemaString(idx);
+	}
+	
+	public String getSchemaString(int idx) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toSchemaString(value);
+	}
+
+	public boolean getBoolean(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getBoolean(idx, false);
+	}
+	
+	public boolean getBoolean(String fieldName, boolean defaultValue) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getBoolean(idx, defaultValue);
+	}	
+	
+	public boolean getBoolean(int idx, boolean defaultValue) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toBoolean(value, defaultValue);
+	}
+	
+	public boolean getDate(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getDate(idx, null);
+	}
+	
+	public boolean getDate(String fieldName, Date defaultValue) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getDate(idx, defaultValue);
+	}	
+	
+	public boolean getDate(int idx, Date defaultValue) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toDate(value, defaultValue);
+	}
+
+	public int getInt(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getInt(idx, 0);
+	}
+	
+	public int getInt(String fieldName, int defaultValue) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getInt(idx, defaultValue);		
+	}
+	
+	public int getInt(int idx, int defaultValue) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toInteger(value, defaultValue);
+	}
+	
+	public BigDecimal getBigDecimal(String fieldName) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getBigDecimal(idx, BigDecimal.ZERO);
+	}
+	
+	public BigDecimal getBigDecimal(String fieldName, BigDecimal defaultValue) throws Exception {
+		int idx = entityMeta.getIndex(fieldName);
+		return getBigDecimal(idx, defaultValue);
+	}
+	
+	public BigDecimal getBigDecimal(int idx, BigDecimal defaultValue) throws Exception {
+		Object value = dataArray[idx];
+		Convertor convertor = entityMeta.getConvertor(idx);
+		return convertor.toBigDecimal(value, defaultValue);
+	}
+	
+	public String getDataName() {
+		return entityMeta.getName();
+	}
+
+	public int getFieldCount() {
+		return entityMeta.getFieldCount();
+	}
+
+	public String[] getLowerNames() {
+		return entityMeta.getLowerNames();
+	}
+
+	public EntityMeta getEntityMeta() {
+		return entityMeta;
+	}
+
+	public boolean isEmptyValue(String fieldName) {
+		int idx = entityMeta.getIndex(fieldName);
+		return isEmptyValue(idx);
+	}
+	
+	public boolean isEmptyValue(int idx) {
+		return dataArray[idx] == null;
+	}
+
+	public void setValueToStatement(int dataIdx, PreparedStatement stmt, int paramIdx) throws SQLException {
+		entityMeta.setValueToStatement(dataArray, dataIdx, stmt, paramIdx);
+	}
+	
+	public void loadInitData() {
+		//TODO
+	}
+
+	public static boolean isDBExists(Entity entity) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance("getCountOfId");
+		namedSQL.setTableName(entity.getDataName()).setParam("id", entity.getQuotedString("id"));
+		int cnt = SQLRunner.getInteger(namedSQL);
+		
+		return cnt > 0;
+	}
+	
+	public boolean isDBExists() throws Exception {
+		return isDBExists(this);
+	}
+	
+	public static void loadDB(Id id, Entity entity) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance("getLineById");
+		namedSQL.setTableName(entity.getDataName()).setParam("id", id.getQuotedValue());
+		SQLRunner.getEntity(namedSQL, entity);
+	}
+	
+	public void loadDB(Id id) throws Exception {
+		loadDB(id, this);
+	}
+	
+	public static void insertDB(Entity entity) throws Exception {
+		if (entity.isEmptyValue("id")) {
+			entity.set("id", Util.newShortGUID());
+		}
+		
+		NamedSQL namedSQL = NamedSQL.getInstance("insert");
+		namedSQL.setTableName(entity.getDataName()).setFieldNames(entity.getEntityMeta(), entity).setValues(entity);
+		SQLRunner.execSQL(namedSQL);
+	}
+	
+	public void insertDB() throws Exception {
+		insertDB(this);
+	}
+	
+	public static void updateDB(Entity entity) throws Exception {
+		if (entity.isEmptyValue("id")) {
+			entity.set("id", Util.newShortGUID());
+		}
+		
+		NamedSQL namedSQL = NamedSQL.getInstance("updateById");
+		namedSQL.setTableName(entity.getDataName()).setFieldNameValues(entity);
+		namedSQL.setParam("fieldNameId", "id").setParam("id", entity.getQuotedString("id"));
+
+		SQLRunner.execSQL(namedSQL);
+	}
+	
+	public void updateDB() throws Exception {
+		updateDB(this);
+	}
+	
+	public void saveDB() throws Exception {
+		if (isEmptyValue("id")) {
+			set("id", Util.newShortGUID());
+		}
+		
+		boolean exists = isDBExists();
+		
+		if (exists) {
+			updateDB();
+		}
+		else {
+			insertDB(); 
+		}		
+	}
+	
+	public static void deleteDB(Entity entity) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance("deleteById");
+		namedSQL.setTableName(entity.getDataName()).setParam("id", entity.getString("id"));
+	}
+
+	public void deleteDB() throws Exception {
+		deleteDB(this);
+	}
+
+	public int getDBCount(Filter filter) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public Object getDataValue(String name) {
+		return getValue(name);
+	}
+
+	@Override
+	public List<String> getDataNameList() {
+		String[] lowerNames = entityMeta.getLowerNames();
+		return Arrays.asList(lowerNames);
+	}
+
+	@Override
+	public boolean containsData(String name) {
+		return entityMeta.contains(name);
+	}
+
+	@Override
+	public void setDataValue(String name, Object value) {
+		set(name, value);
+	}
+
+}
diff --git a/src/frame/data/EntitySet.java b/src/frame/data/EntitySet.java
new file mode 100644
index 0000000..a6c746e
--- /dev/null
+++ b/src/frame/data/EntitySet.java
@@ -0,0 +1,118 @@
+package frame.data;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import frame.data.meta.EntityMeta;
+import frame.data.meta.MetaContainer;
+import frame.object.data.Filter;
+import frame.object.data.OrderBy;
+import frame.persist.NamedSQL;
+import frame.persist.SQLRunner;
+
+public class EntitySet implements Iterable<Entity> {
+
+	private EntityMeta entityMeta;
+	private List<Entity> entityList;
+	private int pos;
+
+	public EntitySet(String dataName) throws Exception {
+		this(MetaContainer.get(dataName), 15);
+	}
+	
+	public EntitySet(EntityMeta tableMeta) {
+		this(tableMeta, 15);
+	}
+
+	public EntitySet(EntityMeta entityMeta, int size) {
+		this.entityMeta = entityMeta;
+		entityList = new ArrayList<Entity>(size);
+		pos = -1;
+	}
+
+	public Entity append() {
+		Entity entity = new Entity(entityMeta);
+		entityList.add(entity);
+
+		return entity;
+	}
+
+	public Entity next() {
+		pos++;
+
+		if (pos < entityList.size()) {
+			return entityList.get(pos);
+		}
+
+		return null;
+	}
+
+	public String[] getLowerNames() {
+		return entityMeta.getLowerNames();
+	}
+
+	public boolean isEmpty() {
+		return entityList.isEmpty();
+	}
+
+	public String getDataName() {
+		return entityMeta.getName();
+	}
+
+	public int getFieldCount() {
+		return entityMeta.getFieldCount();
+	}
+
+	public void first() {
+		pos = -1;
+	}
+
+	public EntityMeta getEntityMeta() {
+		return entityMeta;
+	}
+
+	@Override
+	public Iterator<Entity> iterator() {
+		return entityList.iterator();
+	}
+
+	public void clear() {
+		entityList.clear();
+		pos = -1;
+	}
+
+	public int size() {
+		return entityList.size();
+	}
+
+	public static void loadDB(EntitySet entitySet, Filter filter, OrderBy orderBy) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance("getDataSet");
+		namedSQL.setTableName(entitySet.getDataName()).setFilter(filter).setOrderBy(orderBy);		
+		SQLRunner.getEntitySet(namedSQL, entitySet);
+	}
+	
+	public void loadDB(Filter filter, OrderBy orderBy) throws Exception {
+		loadDB(this, filter, orderBy);
+	}
+
+	public void loadDB(EntitySet entitySet, Filter filter, Page page, OrderBy orderBy) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance("getSetByPage");
+		namedSQL.setTableName(entitySet.getDataName()).setFilter(filter).setPage(page).setOrderBy(orderBy);		
+		SQLRunner.getEntitySet(namedSQL, entitySet);
+	}
+	
+	public void loadDB(Filter filter, Page page, OrderBy orderBy) throws Exception {
+		loadDB(this, filter, page, orderBy);
+	}
+
+	public int getDBCount(Filter filter) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public boolean hasNext() {
+		return pos <= entityList.size();
+	}
+
+}
diff --git a/src/frame/data/IDataConsumer.java b/src/frame/data/IDataConsumer.java
new file mode 100644
index 0000000..f6d2782
--- /dev/null
+++ b/src/frame/data/IDataConsumer.java
@@ -0,0 +1,13 @@
+package frame.data;
+
+import java.util.List;
+
+public interface IDataConsumer {
+
+	List<String> getDataNameList();
+
+	boolean containsData(String name);
+	
+	void setDataValue(String name, Object value);
+
+}
diff --git a/src/frame/data/IDataProvider.java b/src/frame/data/IDataProvider.java
new file mode 100644
index 0000000..8bf05ac
--- /dev/null
+++ b/src/frame/data/IDataProvider.java
@@ -0,0 +1,13 @@
+package frame.data;
+
+import java.util.List;
+
+public interface IDataProvider {
+
+	List<String> getDataNameList();
+	
+	boolean containsData(String name);
+
+	Object getDataValue(String name);
+
+}
diff --git a/src/frame/data/Page.java b/src/frame/data/Page.java
new file mode 100644
index 0000000..adfc2a8
--- /dev/null
+++ b/src/frame/data/Page.java
@@ -0,0 +1,156 @@
+package frame.data;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import frame.expression.IVariantRequestListener;
+import frame.expression.VariantRequestParams;
+
+public class Page implements IVariantRequestListener, IDataProvider {  
+	
+	private static Set<String> parameterNames;
+    private int pageSize;  
+    private int recordCount;  
+    private int pageNo;
+  
+    static {
+    	parameterNames = new HashSet<String>();
+    	parameterNames.add("pagesize");
+    	parameterNames.add("recordcount");
+    	parameterNames.add("pageno");
+    	parameterNames.add("beginno");    	
+    }
+    
+    public Page(int recordCount) { 
+    	this.pageSize = 20;
+    	this.pageNo = 1;
+        this.recordCount = recordCount;
+    }  
+    
+	public Page(int totalCount, DataPool dataPool) {
+    	this.pageSize = dataPool.getInt("pagesize", 20);
+    	this.pageNo = dataPool.getInt("pageno", 1);
+        this.recordCount = totalCount;
+	}
+
+	public int getBeginRecordNo() { 
+    	int recordNo = pageSize * (pageNo - 1) + 1; 
+        return recordNo;  
+    }  
+    
+    public int getBeginRecordNo_1() { 
+    	int recordNo = getBeginRecordNo();
+        return recordNo - 1;  
+    } 
+    
+    public int getEndRecordNo() {  
+    	int recordNo = pageSize * pageNo;
+        return Math.min(recordNo, recordCount);  
+    }  
+    
+    public int getPageSize() {  
+        return pageSize;  
+    }  
+  
+    public int getPageNo() {  
+        return pageNo;
+    }  
+  
+    public int getRecordCount() {  
+        return recordCount;  
+    }  
+  
+    public int getPageCount() {  
+        return (int)Math.ceil(recordCount * 1.0d / pageSize);
+    }  
+  
+    public void setRecordCount(int count) {
+    	this.recordCount = count;
+    }
+  
+    public void setPageSize(int value) { 
+    	if (value <= 0) {
+    		return;
+    	}
+    	
+       	pageSize = value;  
+    }  
+    
+	public void setPageNo(int pageNo) {
+		this.pageNo = pageNo;
+	}
+
+	public void set(String name, String value) {
+		name = name.toLowerCase();
+		
+		if ("pageno".equals(name)) {
+			setPageNo(Integer.parseInt(value));
+		}
+		else if ("pagesize".equals(name)) {
+			setPageSize(Integer.parseInt(value));			
+		}
+	}
+
+ 	public String toString() {
+		StringBuilder result = new StringBuilder();
+		
+		result.append("size=").append(pageSize).append(",");
+		result.append("recordCount=").append(recordCount).append(",");
+		result.append("pageNo=").append(pageNo);
+		
+		return result.toString();
+	}
+
+	@Override
+	public String getStringValue(String name, VariantRequestParams params) {
+		if ("pageSize".equalsIgnoreCase(name)) {
+			return String.valueOf(pageSize);
+		}
+		else if ("recordCount".equalsIgnoreCase(name)) {
+			return String.valueOf(recordCount);
+		}
+		else if ("pageNo".equalsIgnoreCase(name)) {
+			return String.valueOf(pageNo);
+		}
+		else if ("beginNo".equalsIgnoreCase(name)) {
+			int beginNo = getBeginRecordNo_1();
+			return String.valueOf(beginNo);
+		}
+		else if ("endNo".equalsIgnoreCase(name)) {
+			int endNo = getEndRecordNo();
+			return String.valueOf(endNo);
+		}
+		
+		return null;
+	}
+
+	@Override
+	public List<String> getVariantNames() {
+		return new ArrayList<String>(parameterNames);
+	}
+
+	public static Set<String> getVarinatNameSet() {
+		return parameterNames;
+	}
+
+	@Override
+	public List<String> getDataNameList() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean containsData(String name) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public Object getDataValue(String name) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+}  
\ No newline at end of file
diff --git a/src/frame/data/PropertyIterator.java b/src/frame/data/PropertyIterator.java
new file mode 100644
index 0000000..44a17f4
--- /dev/null
+++ b/src/frame/data/PropertyIterator.java
@@ -0,0 +1,35 @@
+package frame.data;
+
+import java.util.Iterator;
+
+import frame.data.reader.ObjectReader;
+import frame.data.reader.PropertyReader;
+
+public class PropertyIterator implements Iterator<PropertyReader> {
+
+	private ObjectReader objectReader;
+	private int size;
+	private int pos;
+	
+	public PropertyIterator(ObjectReader objectReader) {
+		this.objectReader = objectReader;
+		this.size = objectReader.size();
+		this.pos = 0;
+	}
+	
+	@Override
+	public boolean hasNext() {
+		return pos < size;
+	}
+
+	@Override
+	public PropertyReader next() {
+		return objectReader.getPropertyReader(pos++);
+	}
+
+	@Override
+	public void remove() {
+		
+	}
+
+}
diff --git a/src/frame/data/Variant.java b/src/frame/data/Variant.java
new file mode 100644
index 0000000..ad573a9
--- /dev/null
+++ b/src/frame/data/Variant.java
@@ -0,0 +1,270 @@
+package frame.data;
+
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.util.Date;
+
+import org.apache.log4j.Logger;
+
+import frame.util.Util;
+
+public class Variant {
+
+	private Object value;
+	private DataType type;
+	private static Logger logger;
+	
+	
+	static {
+		logger = Logger.getLogger(Variant.class);
+	}
+	
+	public Variant() {
+		value = null;
+	}
+	
+	public Variant(Boolean value) {
+		setValue(value);
+	}
+	
+	public Variant(Integer value) {
+		setValue(value);
+	}
+	
+	public Variant(Double value) {
+		setValue(value);
+	}
+	
+	public Variant(BigDecimal value) {
+		setValue(value);
+	}
+	
+	public Variant(Date value) {
+		setValue(value);
+	}
+	
+	public Variant(String value) {
+		setValue(value);
+	}
+
+	public void setValue(Boolean value) {
+		this.value = value;
+		type = DataType.Int;		
+	}
+	
+	public void setValue(Integer value) {
+		this.value = value;
+		type = DataType.Int;
+	}
+
+	public void setValue(Double value) {
+		this.value = value;
+		type = DataType.Double;
+	}
+	
+	public void setValue(BigDecimal value) {
+		this.value = value;
+		type = DataType.Decimal;
+	}	
+
+	public void setValue(Date value) {
+		this.value = value;
+		type = DataType.Date;
+	}
+
+	public void setValue(String value) {
+		if ("null".equalsIgnoreCase(value)) {
+			this.value = null;
+		}
+		else {
+			this.value = value;				
+		}
+	
+		type = DataType.String;		
+	}
+
+	public void setValue(Object value, DataType type) {
+		this.value = value;
+		this.type = type;		
+	}
+	
+	public DataType getType() {
+		return type;
+	}
+
+	public Integer getIntValue() {
+		Integer result = null;
+		
+		if (value != null) {
+			Class<?> clazz = value.getClass();
+			
+			if (clazz == Integer.class) {
+				result = (Integer)value;
+			}
+			else if (clazz == BigDecimal.class) {
+				result = ((BigDecimal)value).intValue();				
+			}
+			else if (clazz == String.class) {
+				result = Integer.parseInt((String)value);					
+			}
+			else {
+				String value_str = String.valueOf(value);
+				result = Integer.parseInt(value_str);
+			}
+		}
+		else {
+			result = 0;
+		}
+		
+		return result;
+	}
+	
+	public int getIntValue(int defaultValue) {
+		if (value == null) {
+			return defaultValue;
+		}
+		
+		Integer result = getIntValue();
+		
+		if (result == null) {
+			return defaultValue;
+		}
+		
+		return result;
+	}	
+	
+	public Double getDoubleValue() {
+		if (type == DataType.Int) {
+			return Double.valueOf((Integer)value);
+		}
+		else {
+			try {
+				return (Double)value;				
+			}
+			catch(Exception e) {
+				return Double.valueOf(String.valueOf(value));				
+			}
+		}
+	}
+	
+	public BigDecimal getBigDecimalValue() {
+		if (type == DataType.Int) {
+			return BigDecimal.valueOf((Integer)value);
+		}
+		else {
+			try {
+				return BigDecimal.valueOf((Double)value);				
+			}
+			catch(Exception e) {
+				return BigDecimal.valueOf(Double.valueOf(String.valueOf(value)));			
+			}
+		}
+	}
+	
+	public Long getLongValue() {
+		return (Long) value;
+	}
+
+	public Date getDateValue() throws ParseException {
+		Date result = null;
+		
+		if (DataType.Date == type) {
+			result = (Date)value;
+		}
+		else if (DataType.String == type) {
+			result = Util.StringToDate(value.toString());
+		}
+		else if (DataType.Int == type) {
+			logger.error("can not parse int to date");
+		}
+		else if (DataType.Double == type) {
+			logger.error("can not parse double to date");			
+		}
+		
+		return result;
+	}
+	
+	public java.sql.Timestamp getSqlDateValue() {
+		return new java.sql.Timestamp(((Date)value).getTime());
+	}	
+
+	public String getStringValue() {
+		String result = null;
+		
+		if (value != null) {
+			if (type == DataType.Date) {
+				result = Util.DataTimeToString((Date)value); 
+			}
+		}
+		
+		return result;
+	}
+	
+	public String getStringValue(String defaultValue) {
+		if (value != null) {
+			if (DataType.Date == type) {
+				String result = value.toString();
+				if (result.length() > 15) {
+					return result.substring(0, 16);
+				}
+			}
+
+			return value.toString();
+		}
+		else {
+			return defaultValue;
+		}
+	}
+	
+	public boolean getBooleanValue() {
+		String str = getStringValue();
+		
+		boolean result = "T".equalsIgnoreCase(str);
+		result = result || "True".equalsIgnoreCase(str);
+		result = result || "Y".equalsIgnoreCase(str);
+		result = result || "Yes".equalsIgnoreCase(str);		
+		
+		return result;
+	}
+	
+	public boolean getBooleanValue(boolean defaultValue) {
+		String str = getStringValue();
+		
+		if (Util.isEmptyStr(str)) {
+			return defaultValue;
+		}
+		
+		boolean result = "T".equalsIgnoreCase(str);
+		result = result || "True".equalsIgnoreCase(str);
+		result = result || "Y".equalsIgnoreCase(str);
+		result = result || "Yes".equalsIgnoreCase(str);		
+		
+		return result;
+	}
+	
+	public Object getValue() {
+		return value;
+	}
+
+	public boolean isNull() {
+		return value == null;
+	}
+	
+	public boolean isEmpty() {
+		String str = getStringValue();
+		return Util.isEmptyStr(str);
+	}
+	
+	public void setNull() {
+		value = null;
+	}	
+	
+	public void clear() {
+		value = null;
+	}
+
+	public String toString() {
+		return getStringValue();
+	}
+	
+}
diff --git a/src/frame/data/convert/BigDecimalTranslator.java b/src/frame/data/convert/BigDecimalTranslator.java
new file mode 100644
index 0000000..a8fb5b2
--- /dev/null
+++ b/src/frame/data/convert/BigDecimalTranslator.java
@@ -0,0 +1,128 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import frame.data.Variant;
+import frame.util.Util;
+
+
+public class BigDecimalTranslator extends Convertor {
+
+	public Object loadToObject(String value) throws Exception {
+		if (Util.isEmptyStr(value)) {
+			return null;
+		}
+		
+		return BigDecimal.valueOf(Double.valueOf(value));
+	}
+	
+	public Variant loadToVariant(String value) throws Exception {
+		if (value == null) {
+			return new Variant();
+		}
+		
+		BigDecimal result = BigDecimal.valueOf(Double.valueOf(value));
+		return new Variant(result);
+	}
+
+	public String toString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return value.toString();
+	}
+
+	public String toSqlString(Object value) throws Exception {
+		return String.valueOf(value);
+	}
+	
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception	{
+		return toSqlString(value);
+	}
+
+	public String toJSONString(Object value) throws Exception {
+		if (value == null) {
+			return "null";
+		}
+		
+		return value.toString();
+	}
+
+	public Integer toInteger(Object object) throws Exception {
+		if (object == null) {
+			return 0;
+		}
+
+		BigDecimal value = (BigDecimal)object;
+		return value.intValue();
+	}
+	
+	@Override
+	public String toSchemaString(Object value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object, BigDecimal defaultValue)
+			throws Exception {
+		BigDecimal bigDecimal = toBigDecimal(object);
+			
+		return bigDecimal == null ? defaultValue : bigDecimal;
+	}
+
+	@Override
+	public boolean toBoolean(Object value, boolean defaultValue) throws Exception {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean toDate(Object value, Date defaultValue) throws Exception {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		if (object == null) {
+			return 0.0;
+		}
+		
+		BigDecimal value = (BigDecimal)object;
+		return value.doubleValue();
+	}
+
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		if (object == null) {
+			return BigDecimal.valueOf(0);
+		}
+		
+		return (BigDecimal)object;
+	}
+	
+	public Boolean toBoolean(Object object) throws Exception {
+		BigDecimal value = toBigDecimal(object);
+		return !value.equals(0);
+	}
+
+	public Date toDate(Object object) throws Exception {
+		return null;
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		return toBigDecimal(value);
+	}
+
+	@Override
+	public int toInteger(Object value, int defaultValue) throws Exception {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+
+
+}
diff --git a/src/frame/data/convert/BooleanTranslator.java b/src/frame/data/convert/BooleanTranslator.java
new file mode 100644
index 0000000..e517fbb
--- /dev/null
+++ b/src/frame/data/convert/BooleanTranslator.java
@@ -0,0 +1,112 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import frame.data.DataType;
+import frame.data.Variant;
+
+
+public class BooleanTranslator extends Convertor {
+
+	
+	public Object loadToObject(String value) throws Exception {
+		if (value == null) {
+			return false;
+		}
+		
+		value = value.toLowerCase();
+		
+		if ("t".equals(value)) {
+			return true;
+		}
+		
+		if ("true".equals(value)) {
+			return true;
+		}
+		
+		if ("y".equals(value)) {
+			return true;
+		}
+		
+		if ("yes".equals(value)) {
+			return true;
+		}
+		
+		return false;
+	}
+	
+	public Variant loadToVariant(String value) throws Exception {
+		Object object = loadToObject(value);
+		
+		Variant variant = new Variant();
+		variant.setValue(object, DataType.Boolean);
+		
+		return variant;
+	}
+	
+	public String toString(Object value) throws Exception {
+		if (value != null) {
+			Boolean bool = (Boolean) value;
+			return String.valueOf(bool);
+		}
+		
+		return null;
+	}
+
+	public String toSqlString(Object value) throws Exception {
+		if (value != null) {
+			Boolean bool = (Boolean) value;
+			
+			if (bool) {
+				return "T";
+			}
+			else {
+				return "F";
+			}
+		}
+		
+		return null;
+	}
+	
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception	{
+		return toSqlString(value);
+	}
+	
+	public String toJSONString(Object value) throws Exception {
+		if (value != null) {
+			Boolean bool = (Boolean) value;
+			return String.valueOf(bool);
+		}
+		
+		return "null";
+	}
+
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		throw new Exception("can not translate boolean (" + object + ") to Integer");
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		throw new Exception("can not translate boolean (" + object + ") to Double");
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		throw new Exception("can not translate boolean (" + object + ") to BigDecimal");
+	}
+	
+	public Boolean toBoolean(Object object) throws Exception {
+		return (Boolean)object;
+	}
+
+	public Date toDate(Object object) throws Exception {
+		throw new Exception("can not translate boolean (" + object + ") to Date");
+	}
+
+	public Object toSelfType(Object value) throws Exception {
+		return toBoolean(value);
+	}
+
+}
diff --git a/src/frame/data/convert/Convertor.java b/src/frame/data/convert/Convertor.java
new file mode 100644
index 0000000..7b84806
--- /dev/null
+++ b/src/frame/data/convert/Convertor.java
@@ -0,0 +1,132 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import frame.data.DataType;
+import frame.data.Variant;
+
+public abstract class Convertor {
+	
+	protected String format;
+	private static Map<Class<?>, Class<? extends Convertor>> classTranslatorMap;
+	private static Map<DataType, Class<? extends Convertor>> dataTypeTranslatorMap;
+	
+	
+	static {
+		initClassTranslatorMap();
+		initDataTypeTranslatorMap();
+	}
+	
+	public static Convertor getInstance(Class<?> type) throws Exception {
+		return getInstance(type, null);
+	}
+	
+	public static Convertor getInstance(DataType type) throws Exception {
+		return getInstance(type, null);
+	}
+	
+	public static Convertor getInstance(Class<?> type, String format) throws Exception {
+		Convertor result = null;
+		
+		Class<? extends Convertor> translatorClass = classTranslatorMap.get(type);
+		
+		if (translatorClass == null) {
+			throw new Exception("can not create translator for: " + type);
+		}
+
+		result = translatorClass.newInstance();
+		result.setFormat(format);
+		
+		return result;
+	}
+	
+	public static Convertor getInstance(DataType type, String format) throws Exception {
+		Convertor result = null;
+		
+		Class<? extends Convertor> translatorClass = dataTypeTranslatorMap.get(type);
+		
+		if (translatorClass == null) {
+			throw new Exception("can not create translator for: " + type);
+		}
+
+		result = translatorClass.newInstance();
+		result.setFormat(format);
+		
+		return result;
+	}
+
+	public abstract int toInteger(Object value, int defaultValue) throws Exception;
+	
+	public abstract String toSqlString(Object value) throws Exception;
+	
+	public abstract String toSqlString(String prefix, Object value, String suffix)throws Exception;
+
+	public abstract String toJSONString(Object value) throws Exception;
+	
+	public abstract String toSchemaString(Object value) throws Exception; 
+
+	public abstract Double toDouble(Object object)throws Exception;
+
+	public abstract BigDecimal toBigDecimal(Object object, BigDecimal defaultValue) throws Exception;;
+	
+	public abstract boolean toBoolean(Object value, boolean defaultValue) throws Exception;
+
+	public abstract boolean toDate(Object value, Date defaultValue) throws Exception;
+
+	public abstract Object toSelfType(Object value) throws Exception;;
+	
+	public abstract Object loadToObject(String value) throws Exception;
+	
+	public abstract Variant loadToVariant(String value) throws Exception;
+	
+	public abstract String toString(Object value) throws Exception;
+	
+	public void setFormat(String format) {
+		this.format = format;
+	}
+	
+	public String getFormat() {
+		return format;
+	}
+
+	
+	
+	private static void initClassTranslatorMap() {
+		classTranslatorMap = new HashMap<Class<?>, Class<? extends Convertor>>();
+		
+		classTranslatorMap.put(String.class, StringTranslator.class);
+		classTranslatorMap.put(Integer.class, IntegerTranslator.class);
+		classTranslatorMap.put(int.class, IntegerTranslator.class);
+		classTranslatorMap.put(BigInteger.class, IntegerTranslator.class);
+		classTranslatorMap.put(Double.class, DoubleTranslator.class);
+		classTranslatorMap.put(double.class, DoubleTranslator.class);
+		classTranslatorMap.put(Float.class, DoubleTranslator.class);
+		classTranslatorMap.put(float.class, DoubleTranslator.class);
+		classTranslatorMap.put(BigDecimal.class, BigDecimalTranslator.class);
+		classTranslatorMap.put(Date.class, DateTranslator.class);
+		classTranslatorMap.put(Boolean.class, BooleanTranslator.class);
+		classTranslatorMap.put(boolean.class, BooleanTranslator.class);
+		classTranslatorMap.put(Object.class, ObjectTranslator.class);
+		classTranslatorMap.put(Long.class, LongTranslator.class);
+	}
+
+	private static void initDataTypeTranslatorMap() {
+		dataTypeTranslatorMap = new HashMap<DataType, Class<? extends Convertor>>();
+		
+		dataTypeTranslatorMap.put(DataType.String, StringTranslator.class);
+		dataTypeTranslatorMap.put(DataType.Int, IntegerTranslator.class);
+		dataTypeTranslatorMap.put(DataType.Double, DoubleTranslator.class);
+		dataTypeTranslatorMap.put(DataType.Decimal, BigDecimalTranslator.class);
+		dataTypeTranslatorMap.put(DataType.Date, DateTranslator.class);
+		dataTypeTranslatorMap.put(DataType.Boolean, BooleanTranslator.class);
+	}
+
+	public static boolean containsType(Class<?> type) {
+		return classTranslatorMap.containsKey(type);
+	}
+
+
+}
diff --git a/src/frame/data/convert/DateTranslator.java b/src/frame/data/convert/DateTranslator.java
new file mode 100644
index 0000000..3214fe3
--- /dev/null
+++ b/src/frame/data/convert/DateTranslator.java
@@ -0,0 +1,108 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import frame.data.Variant;
+import frame.util.Util;
+
+
+public class DateTranslator extends Convertor {
+
+	private static String DefaultFormat = "yyyy-MM-dd HH:mm:ss";
+			
+	
+	public Object loadToObject(String value) throws Exception {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.parse(value);
+	}
+	
+	public Variant loadToVariant(String value) throws Exception {
+		if (value == null) {
+			return new Variant();
+		}
+		
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		Date date = sdf.parse(value);
+		
+		return new Variant(date);
+	}
+
+	public String toString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		if (value instanceof Date) {
+			Date date = (Date)value;
+			
+			return Util.DataTimeToString(date, format);
+		}
+		
+		return value.toString();
+	}
+	
+	public String toSqlString(Object value) throws Exception {
+		Date date = new Date();
+		return Util.newDBDateString(date);
+	}
+	
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception	{
+		return toSqlString(value);
+	}
+
+	public String toJSONString(Object value) throws Exception {
+		if (value == null) {
+			return "null";
+		}
+		
+		if (value instanceof Date) {
+			Date date = (Date)value;
+			
+			return "\"" + Util.DataTimeToString(date, format) + "\"";
+		}
+		
+		return "\"" + value.toString() + "\"";
+	}
+	
+	public void setFormat(String format) {
+		if (Util.isEmptyStr(format)) {
+			this.format = DefaultFormat;
+		}
+		else {
+			this.format = format;
+		}
+	}
+
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		throw new Exception("can not translate date (" + object + ") to Integer");
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		throw new Exception("can not translate date (" + object + ") to Double");
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		throw new Exception("can not translate date (" + object + ") to BigDecimal");
+	}
+	
+	@Override
+	public Boolean toBoolean(Object object) throws Exception {
+		throw new Exception("can not translate date (" + object + ") to BigDecimal");
+	}
+
+	@Override
+	public Date toDate(Object object) throws Exception {
+		return (Date) object;
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		return toDate(value);
+	}
+
+}
diff --git a/src/frame/data/convert/DoubleTranslator.java b/src/frame/data/convert/DoubleTranslator.java
new file mode 100644
index 0000000..c19991a
--- /dev/null
+++ b/src/frame/data/convert/DoubleTranslator.java
@@ -0,0 +1,129 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import frame.data.Variant;
+import frame.util.Util;
+
+
+public class DoubleTranslator extends Convertor {
+
+	public Object loadToObject(String value) throws Exception {
+		if (Util.isEmptyStr(value)) {
+			return null;
+		}
+		
+		return Double.valueOf(value);
+	}
+	
+	public Variant loadToVariant(String value) throws Exception {
+		if (value == null) {
+			return new Variant();
+		}
+		
+		Double result = Double.valueOf(value);
+		
+		return new Variant(result);
+	}
+
+	public String toString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return value.toString();
+	}
+
+	public String toSqlString(Object value) throws Exception {
+		return String.valueOf(value);
+	}
+	
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception	{
+		return toSqlString(value);
+	}
+
+	public String toJSONString(Object value) throws Exception {
+		if (value == null) {
+			return "null";
+		}
+		
+		return value.toString();
+	}
+
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		if (object == null) {
+			return 0;
+		}
+		
+		Double value = (Double)object;
+		return value.intValue();
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		if (object == null) {
+			return 0.0;
+		}
+		
+		return (Double)object;
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		if (object == null) {
+			return BigDecimal.valueOf(0);
+		}
+		
+		return BigDecimal.valueOf((Double)object);
+	}
+	
+	@Override
+	public Boolean toBoolean(Object object) throws Exception {
+		Double value = toDouble(object);
+		return value != 0;
+	}
+
+	@Override
+	public Date toDate(Object object) throws Exception {
+		Integer value = toInteger(object);
+		
+		if (value >= 19500101 && value <= 21000101) {
+			String string = String.valueOf(value.intValue());
+			DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+			return dateFormat.parse(string);
+		}
+		else if (value > (1950 - 1900) * 365 && value < (2100 - 1900) * 365) {
+			int dateValue = value.intValue();
+			double secValue = value - dateValue;
+			
+			Calendar calendar = Calendar.getInstance();
+			calendar.set(Calendar.YEAR, 1900);
+			calendar.set(Calendar.MONTH, 0);
+			calendar.set(Calendar.DAY_OF_MONTH, 1);
+			calendar.set(Calendar.HOUR_OF_DAY, 0);
+			calendar.set(Calendar.MINUTE, 0);
+			calendar.set(Calendar.SECOND, 0);
+			calendar.add(Calendar.DATE, value - 2);
+			
+			Date dayDate = calendar.getTime();
+			long sec = Math.round(secValue * 24 * 3600 * 1000);
+			
+			Date result = new Date();
+			result.setTime(dayDate.getTime() + sec);
+			return result;
+		}
+		
+		return null;
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		return toDouble(value);
+	}
+
+}
diff --git a/src/frame/data/convert/IntegerTranslator.java b/src/frame/data/convert/IntegerTranslator.java
new file mode 100644
index 0000000..56e9ec4
--- /dev/null
+++ b/src/frame/data/convert/IntegerTranslator.java
@@ -0,0 +1,120 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import frame.data.Variant;
+
+
+public class IntegerTranslator extends Convertor {
+
+	
+	public Object loadToObject(String value) throws Exception {
+		return Integer.valueOf(value);
+	}
+
+	public Variant loadToVariant(String value) throws Exception {
+		if (value == null) {
+			return new Variant();
+		}
+		
+		Integer result = Integer.valueOf(value);
+		
+		return new Variant(result);
+	}
+	
+	public String toString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return value.toString();
+	}
+	
+	public String toSqlString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return String.valueOf(value);
+	}
+	
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception	{
+		return toSqlString(value);
+	}
+
+	public String toJSONString(Object value) throws Exception {
+		if (value == null) {
+			return "null";
+		}
+		
+		return value.toString();
+	}
+
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		if (object == null) {
+			return 0;
+		}
+		
+		return (Integer)object;
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		if (object == null) {
+			return 0.0;
+		}
+		
+		return Double.valueOf((Integer)object);
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		if (object == null) {
+			return BigDecimal.valueOf(0);
+		}
+		
+		return BigDecimal.valueOf((Integer)object);
+	}
+	
+	@Override
+	public Boolean toBoolean(Object object) throws Exception {
+		Integer value = toInteger(object);
+		return value != 0;
+	}
+
+	@Override
+	public Date toDate(Object object) throws Exception {
+		Integer value = toInteger(object);
+		
+		if (value >= 19500101 && value <= 21000101) {
+			String string = String.valueOf(value);
+			DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+			return dateFormat.parse(string);
+		}
+		else if (value > (1950 - 1900) * 365 && value < (2100 - 1900) * 365) {
+			Calendar calendar = Calendar.getInstance();
+			calendar.set(Calendar.YEAR, 1900);
+			calendar.set(Calendar.MONTH, 0);
+			calendar.set(Calendar.DAY_OF_MONTH, 1);
+			calendar.set(Calendar.HOUR_OF_DAY, 0);
+			calendar.set(Calendar.MINUTE, 0);
+			calendar.set(Calendar.SECOND, 0);
+			calendar.add(Calendar.DATE, value - 2);
+			
+			return calendar.getTime();
+		}
+		
+		return null;
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		return toInteger(value);
+	}
+
+}
diff --git a/src/frame/data/convert/LongTranslator.java b/src/frame/data/convert/LongTranslator.java
new file mode 100644
index 0000000..dae1afe
--- /dev/null
+++ b/src/frame/data/convert/LongTranslator.java
@@ -0,0 +1,82 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import frame.data.Variant;
+//TODO nothing
+
+public class LongTranslator extends Convertor {
+
+	@Override
+	public Object loadToObject(String value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Variant loadToVariant(String value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String toString(Object value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String toSqlString(Object value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String toJSONString(Object value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		Number _object = (Number)object;
+		return _object.intValue();
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Boolean toBoolean(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Date toDate(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/src/frame/data/convert/ObjectTranslator.java b/src/frame/data/convert/ObjectTranslator.java
new file mode 100644
index 0000000..374a52e
--- /dev/null
+++ b/src/frame/data/convert/ObjectTranslator.java
@@ -0,0 +1,193 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import frame.data.Variant;
+
+
+public class ObjectTranslator extends Convertor {
+
+	@Override
+	public Object loadToObject(String value) throws Exception {
+		return value;
+	}
+
+	@Override
+	public Variant loadToVariant(String value) throws Exception {
+		if (value == null) {
+			return new Variant();
+		}
+		
+		return new Variant(value);
+	}
+	
+	@Override
+	public String toString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return value.toString();
+	}
+
+	@Override
+	public String toSqlString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		if (value instanceof String) {
+			return "'" + value + "'";
+		}
+		
+		if (value instanceof Date) {
+			return "'" + value + "'";
+		}		
+		
+		return value.toString();
+	}
+
+	@Override
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		String result = value.toString();
+		
+		if (prefix != null) {
+			result = result + prefix;
+		}
+		
+		if (suffix != null) {
+			result = result + suffix;
+		}
+		
+		if (value instanceof String) {
+			return "'" + result + "'";
+		}
+		
+		if (value instanceof Date) {
+			return "'" + result + "'";
+		}	
+		
+		return result;
+	}
+
+	@Override
+	public String toJSONString(Object value) throws Exception {
+		if (value == null) {
+			return "null";
+		}
+		
+		return "\"" + value.toString() + "\"";		
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Boolean toBoolean(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	@Override
+	public boolean toBoolean(Object value, boolean defaultValue)
+			throws Exception {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	@Override
+	public Date toDate(Object object) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		if (object == null) {
+			return 0;
+		}
+		
+		if (object instanceof Integer) {
+			return (Integer)object;
+		}
+		
+		if (object instanceof Double) {
+			return ((Double)object).intValue();
+		}
+		
+		if (object instanceof Float) {
+			return ((Float)object).intValue();
+		}
+		
+		if (object instanceof Long) {
+			return ((Long)object).intValue();
+		}
+		
+		if (object instanceof BigDecimal) {
+			return ((BigDecimal)object).intValue();
+		}
+		
+		if (object instanceof String) {
+			return Integer.valueOf((String)object);
+		}
+		
+		return Integer.valueOf(String.valueOf(object));
+	}
+	
+	public String getString(Object object) {
+		if (object == null) {
+			return null;
+		}
+		
+		if (object instanceof String) {
+			return (String)object;
+		}
+		
+		return String.valueOf(object);
+	}
+
+	public BigDecimal getBigDecimal(Object object) {
+		if (object == null) {
+			return null;
+		}
+		
+		if (object instanceof BigDecimal) {
+			return ((BigDecimal)object);
+		}
+		
+		if (object instanceof Long) {
+			BigDecimal value = new BigDecimal((Long)object);
+			return value;
+		}
+		
+		if (object instanceof String) {
+			BigDecimal value = new BigDecimal((String)object);
+			return value;
+		}
+		
+		return (BigDecimal)object;
+	}
+
+
+
+}
diff --git a/src/frame/data/convert/StringTranslator.java b/src/frame/data/convert/StringTranslator.java
new file mode 100644
index 0000000..6f688da
--- /dev/null
+++ b/src/frame/data/convert/StringTranslator.java
@@ -0,0 +1,174 @@
+package frame.data.convert;
+
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import frame.data.Variant;
+
+
+public class StringTranslator extends Convertor {
+
+	
+	public Object loadToObject(String value) throws Exception {
+		return value;
+	}
+
+	public Variant loadToVariant(String value) throws Exception {
+		if (value == null) {
+			return new Variant();
+		}
+		
+		return new Variant(value);
+	}
+
+	public String toString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return value.toString();
+	}
+	
+	public String toSqlString(Object value) throws Exception {
+		if (value == null) {
+			return null;
+		}
+		
+		return "'" + value + "'";
+	}
+
+	public String toSqlString(String prefix, Object value, String suffix) throws Exception	{
+		if (value == null) {
+			return null;
+		}
+		
+		String result = "";
+		
+		if (prefix != null) {
+			result = result + prefix;
+		}
+		
+		result = result + value;
+		
+		if (suffix != null) {
+			result = result + suffix;
+		}
+		
+		return "'" + result + "'";
+	}
+	
+	public String toJSONString(Object value) throws Exception {
+		if (value == null) {
+			return "null";
+		}
+		
+		return "\"" + value.toString() + "\"";
+	}
+
+	@Override
+	public Integer toInteger(Object object) throws Exception {
+		if (object == null) {
+			return 0;
+		}
+		
+		return Integer.valueOf(String.valueOf(object));
+	}
+
+	@Override
+	public Double toDouble(Object object) throws Exception {
+		if (object == null) {
+			return 0.0;
+		}
+		
+		return Double.valueOf(String.valueOf(object));
+	}
+
+	@Override
+	public BigDecimal toBigDecimal(Object object) throws Exception {
+		if (object == null) {
+			return BigDecimal.valueOf(0);
+		}
+		
+		return BigDecimal.valueOf(Double.valueOf(String.valueOf(object)));
+	}
+	
+	@Override
+	public Boolean toBoolean(Object object) throws Exception {
+		if (object == null) {
+			return false;
+		}
+		
+		String value = String.valueOf(object).toLowerCase();
+		
+		if ("t".equals(value)) {
+			return true;
+		}
+		
+		if ("true".equals(value)) {
+			return true;
+		}
+		
+		if ("y".equals(value)) {
+			return true;
+		}
+		
+		if ("yes".equals(value)) {
+			return true;
+		}
+		
+		return false;		
+	}
+
+	@Override
+	public Date toDate(Object object) throws Exception {
+		if (object == null) {
+			return null;
+		}
+		
+		String fomater = null;
+		String string = String.valueOf(object).replace('T', ' ');
+		
+		if (string.indexOf("/") == 4) {
+			fomater = "yyyy/MM/dd";
+		}
+		else if (string.indexOf("/") == 2 || string.indexOf("/") == 1) {
+			fomater = "MM/dd/yyyy";			
+		}
+		else if (string.indexOf("-") == 2 || string.indexOf("-") == 1) {
+			fomater = "MM-dd-yyyy";		
+		}
+		else if (string.indexOf("-") == 4 && string.indexOf(":")<0) {
+			fomater = "yyyy-MM-dd";				
+		}
+		else if (string.indexOf("-") == 4  && string.indexOf(":")>0) {
+			if(string.split(":").length == 3){
+			   fomater = "yyyy-MM-dd HH:mm:ss";
+			}
+			else{
+				string = string + ":00";
+				fomater = "yyyy-MM-dd HH:mm:00";
+			}
+						
+		}		
+		else if (string.indexOf(".") == 2 || string.indexOf(".") == 1) {
+			fomater = "MM.dd.yyyy";	
+		}
+		else if (string.indexOf(".") == 4) {
+			fomater = "yyyy.MM.dd";		
+		}
+		else if (string.indexOf("-") < 0 && string.indexOf("/") < 0) {
+			fomater = "yyyyMMdd";
+		}
+
+		DateFormat dateFormat = new SimpleDateFormat(fomater);
+		return dateFormat.parse(string);
+	}
+
+	@Override
+	public Object toSelfType(Object value) throws Exception {
+		return toString(value);
+	}
+
+}
diff --git a/src/frame/data/meta/EntityMeta.java b/src/frame/data/meta/EntityMeta.java
new file mode 100644
index 0000000..a3b8ecc
--- /dev/null
+++ b/src/frame/data/meta/EntityMeta.java
@@ -0,0 +1,416 @@
+package frame.data.meta;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import frame.data.convert.Convertor;
+import frame.persist.SQLRunner;
+import frame.persist.loader.ResultMetaFieldReader;
+import frame.util.Util;
+
+public class EntityMeta implements Iterable<Field> {
+
+	protected static Logger logger;
+	
+	private String name;
+	private List<Field> fieldList;
+	private String[] names;
+	private String[] lowerNames;
+	private int index_key;
+	private Map<String, Integer> nameIndexMap;
+
+	static {
+		logger = Logger.getLogger(EntityMeta.class);
+	}
+
+	public static EntityMeta getInstance(String tableName) throws Exception {
+		return MetaContainer.get(tableName);
+	}
+
+	public static EntityMeta getInstance(String tableName, boolean refresh) throws Exception {
+		return MetaContainer.get(tableName, refresh);
+	}
+	
+	public EntityMeta(String tableName, IFieldReader fieldReader) throws SQLException {
+		this.name = tableName;
+		nameIndexMap = new HashMap<String, Integer>();
+		fieldList = new ArrayList<Field>();
+
+		initFields(fieldReader);
+	}
+	
+	public static EntityMeta getInstance(ResultSetMetaData metaData) throws Exception {
+		ResultMetaFieldReader fieldReader = new ResultMetaFieldReader(metaData);
+		return new EntityMeta("tablemeta", fieldReader);
+	}
+
+	private void initFields(IFieldReader fieldReader) throws SQLException {
+		String fieldName;
+		int columnType;
+		int fieldLength;
+		int nullable;
+		Field field;
+
+		fieldReader.first();
+
+		while (fieldReader.next()) {
+			fieldName = fieldReader.getFieldName();
+			columnType = fieldReader.getFieldType();
+			fieldLength = fieldReader.getFieldLength();
+			nullable = fieldReader.getNullable();
+
+			if (fieldName == null) {
+				continue;
+			}
+
+			field = new Field(fieldName);
+			fieldList.add(field);
+
+			field.setType(columnType);
+			field.setLength(fieldLength);
+			field.setNullable(nullable);
+		}
+
+		int fieldCount = fieldList.size();
+		names = new String[fieldCount];
+		lowerNames = new String[fieldCount];
+
+		String name;
+		for (int i = 0; i < fieldCount; i++) {
+			field = fieldList.get(i);
+			name = field.getName();
+			names[i] = name;
+
+			name = name.toLowerCase();
+			lowerNames[i] = name;
+			nameIndexMap.put(name, i);
+		}
+	}
+
+	public int getFieldCount() {
+		return fieldList.size();
+	}
+
+	public Iterator<Field> iterator() {
+		return fieldList.iterator();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setPrimaryKey(String keyField) {
+		if (keyField == null) {
+			return;
+		}
+
+		Integer idx = nameIndexMap.get(keyField.toLowerCase());
+
+		if (idx != null) {
+			index_key = idx;
+		}
+	}
+
+	public List<Field> getFields() {
+		return fieldList;
+	}
+
+	public Field get(String name) {
+		if (name == null)
+			return null;
+
+		Integer idx = nameIndexMap.get(name.toLowerCase());
+
+		if (idx == null) {
+			return null;
+		}
+
+		return fieldList.get(idx);
+	}
+
+	public Field get(int idx) {
+		return fieldList.get(idx);
+	}
+
+	public synchronized String getFiledName_Key() throws Exception {
+		if (index_key >= 0) {
+			String keyName = SQLRunner.getPrimaryKeyField(null, name);
+
+			if (keyName == null) {
+				return null;
+			}
+
+			Integer idx = nameIndexMap.get(keyName.toLowerCase());
+
+			if (idx == null) {
+				return null;
+			}
+		}
+
+		if (index_key >= 0) {
+			Field field = fieldList.get(index_key);
+			return field.getName();
+		}
+
+		return "id";
+	}
+
+	public int getIndex_Key() {
+		return index_key;
+	}
+
+	public int getIndex(String fieldName) {
+		if (fieldName == null) {
+			return -2;
+		}
+		
+		return nameIndexMap.get(fieldName.toLowerCase());
+	}
+
+	public String[] getLowerNames() {
+		return lowerNames;
+	}
+
+	public boolean contains(String name) {
+		if (name == null) {
+			return false;
+		}
+
+		name = name.toLowerCase();
+		return nameIndexMap.containsKey(name);
+	}
+
+	public void setObject(Object[] dataArray, String name, Object object) {
+		if (name == null) {
+			return;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return;
+		}
+
+		dataArray[idx] = object;
+	}
+
+	public void setString(Object[] dataArray, String name, String value) throws ParseException {
+		if (name == null) {
+			return;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return;
+		}
+
+		Field field = fieldList.get(idx);
+		Object obj = field.stringToObject(value);
+
+		dataArray[idx] = obj;
+	}
+
+	public String getString(Object[] dataArray, String name, String defaultValue) throws Exception {
+		if (name == null) {
+			return null;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return null;
+		}
+
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		if (obj == null) {
+			return defaultValue;
+		}
+
+		return field.objectToString(obj);
+	}
+
+	public String getString(Object[] dataArray, int idx, String defaultValue) throws Exception {
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		if (obj == null) {
+			return defaultValue;
+		}
+
+		return field.objectToString(obj);
+	}
+
+	public boolean getBoolean(Object[] dataArray, String name) {
+		if (name == null) {
+			return false;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return false;
+		}
+
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToBoolean(obj);
+	}
+
+	public Date getDate(Object[] dataArray, String name) throws ParseException {
+		if (name == null) {
+			return null;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return null;
+		}
+
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToDate(obj);
+	}
+
+	public Integer getInteger(Object[] dataArray, String name) {
+		if (name == null) {
+			return null;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return null;
+		}
+
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToInteger(obj);
+	}
+	
+	public BigDecimal getBigDecimal(Object[] dataArray, String name) {
+		if (name == null) {
+			return null;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return null;
+		}
+
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToBigDecimal(obj);
+	}
+
+	public String getSchemaString(Object[] dataArray, int idx) throws Exception {
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToSchemaString(obj);
+	}
+
+	public String getJSONSString(Object[] dataArray, int idx) throws SQLException {
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToJSONSString(obj);
+	}
+
+	public String getSqlString(Object value, String name) throws Exception {
+		if (name == null) {
+			return null;
+		}
+
+		name = name.toLowerCase();
+		Integer idx = nameIndexMap.get(name);
+
+		if (idx == null) {
+			return null;
+		}
+
+		Field field = fieldList.get(idx);
+		return field.objectToSQLString(value);
+	}
+
+	public String getSQLString(Object[] dataArray, int idx) throws Exception {
+		Field field = fieldList.get(idx);
+		Object obj = dataArray[idx];
+
+		return field.objectToSQLString(obj);
+	}
+
+	public void setValueToStatement(Object[] dataArray, int dataIdx, PreparedStatement stmt, int paramIdx)
+			throws SQLException {
+		Field field = fieldList.get(dataIdx);
+		Object obj = dataArray[dataIdx];
+
+		field.setValueToStatement(obj, stmt, paramIdx);
+	}
+
+	public String getFieldNames() {
+		StringBuffer result = new StringBuffer();
+
+		boolean empty = true;
+
+		for (String name : names) {
+			if (!empty) {
+				result.append(", ");
+			}
+
+			result.append(name);
+			empty = false;
+		}
+
+		return result.toString();
+	}
+
+	public String getDoubleQuotedFieldNames() {
+		StringBuffer result = new StringBuffer();
+
+		boolean empty = true;
+
+		for (String name : names) {
+			if (!empty) {
+				result.append(", ");
+			}
+
+			result.append(Util.doubleQuotedStr(name));
+			empty = false;
+		}
+
+		return result.toString();
+	}
+
+	public Convertor getConvertor(int idx) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/src/frame/data/meta/Field.java b/src/frame/data/meta/Field.java
new file mode 100644
index 0000000..109cd11
--- /dev/null
+++ b/src/frame/data/meta/Field.java
@@ -0,0 +1,410 @@
+package frame.data.meta;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import frame.data.DataType;
+import frame.util.Util;
+
+
+public class Field {
+
+	private static Map<Integer, String> sqlTypeMap;
+	private static Set<Integer> sizableType;
+	private String name;
+	private int sqlType;
+	private DataType type;
+	private int length;
+	private boolean key;
+	private int nullable;
+
+	static {
+		sqlTypeMap = new HashMap<Integer, String>();
+		sizableType = new HashSet<Integer>();
+		initSQLTypeMap();
+	}
+
+	public Field(String name) {
+		nullable = 1;
+		this.name = name;
+	}
+
+	public int getSQLType() {
+		return sqlType;
+	}
+
+	public boolean isKey() {
+		return key;
+	}
+
+	public void setType(DataType value) {
+		type = value;
+		sqlType = value.toSQLTypes();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Object getSQLTypeCode() {
+		String result = sqlTypeMap.get(sqlType);
+
+		if (sizableType.contains(sqlType)) {
+			result = result + "(" + length + ")";
+		}
+
+		return result;
+	}
+
+	public Object getSQLNullCode() {
+		if (nullable == 0) {
+			return "NOT NULL";
+		} else {
+			return "NULL";
+		}
+	}
+
+	public DataType getDataType() {
+		return type;
+	}
+
+	public void setType(int value) {
+		sqlType = value;
+		type = DataType.valueOfTypes(value);
+	}
+
+	public void setLength(int length) {
+		this.length = length;
+	}
+
+	public void setNullable(int nullable) {
+		this.nullable = nullable;
+	}
+
+	public String toString() {
+		StringBuilder result = new StringBuilder();
+
+		result.append("fieldName=").append(name).append(",");
+		result.append("dataType=").append(type).append(",");
+		result.append("length=").append(length);
+
+		return result.toString();
+	}
+
+	public void toString(StringBuilder result) {
+		result.append("fieldName=").append(name).append(",");
+		result.append("dataType=").append(type).append(",");
+		result.append("length=").append(length);
+	}
+
+	private static void initSQLTypeMap() {
+		sqlTypeMap.put(Types.ARRAY, "ARRAY");
+		sqlTypeMap.put(Types.BIGINT, "BIGINT");
+		sqlTypeMap.put(Types.BINARY, "BINARY");
+		sqlTypeMap.put(Types.BIT, "BIT");
+		sqlTypeMap.put(Types.BLOB, "BLOB");
+		sqlTypeMap.put(Types.BOOLEAN, "BOOLEAN");
+		sqlTypeMap.put(Types.CHAR, "CHAR");
+		sqlTypeMap.put(Types.CLOB, "CLOB");
+		sqlTypeMap.put(Types.DATALINK, "DATALINK");
+		sqlTypeMap.put(Types.DATE, "DATE");
+		sqlTypeMap.put(Types.DECIMAL, "DECIMAL");
+		sqlTypeMap.put(Types.DISTINCT, "DISTINCT");
+		sqlTypeMap.put(Types.DOUBLE, "DOUBLE");
+		sqlTypeMap.put(Types.FLOAT, "FLOAT");
+		sqlTypeMap.put(Types.INTEGER, "INTEGER");
+		sqlTypeMap.put(Types.LONGNVARCHAR, "LONGNVARCHAR");
+		sqlTypeMap.put(Types.LONGVARBINARY, "LONGVARBINARY");
+		sqlTypeMap.put(Types.LONGVARCHAR, "LONGVARCHAR");
+		sqlTypeMap.put(Types.NCHAR, "NCHAR");
+		sqlTypeMap.put(Types.NCLOB, "NCLOB");
+		sqlTypeMap.put(Types.NULL, "NULL");
+		sqlTypeMap.put(Types.NUMERIC, "NUMERIC");
+		sqlTypeMap.put(Types.NVARCHAR, "NVARCHAR");
+		sqlTypeMap.put(Types.OTHER, "OTHER");
+		sqlTypeMap.put(Types.REAL, "REAL");
+		sqlTypeMap.put(Types.REF, "REF");
+		sqlTypeMap.put(Types.ROWID, "ROWID");
+		sqlTypeMap.put(Types.SMALLINT, "SMALLINT");
+		sqlTypeMap.put(Types.SQLXML, "SQLXML");
+		sqlTypeMap.put(Types.STRUCT, "STRUCT");
+		sqlTypeMap.put(Types.TIME, "TIME");
+		sqlTypeMap.put(Types.TIMESTAMP, "TIMESTAMP");
+		sqlTypeMap.put(Types.TINYINT, "TINYINT");
+		sqlTypeMap.put(Types.VARBINARY, "VARBINARY");
+		sqlTypeMap.put(Types.VARCHAR, "VARCHAR");
+
+		sizableType.add(Types.ARRAY);
+		sizableType.add(Types.CHAR);
+		sizableType.add(Types.LONGNVARCHAR);
+		sizableType.add(Types.LONGVARBINARY);
+		sizableType.add(Types.LONGVARCHAR);
+		sizableType.add(Types.NCHAR);
+		sizableType.add(Types.NVARCHAR);
+		sizableType.add(Types.SQLXML);
+		sizableType.add(Types.VARBINARY);
+		sizableType.add(Types.VARCHAR);
+	}
+
+	public String objectToString(Object obj) throws Exception {
+		if (obj == null) {
+			return null;
+		}
+
+		if (DataType.String == type) {
+			return (String) obj;
+		} else if (DataType.Int == type) {
+			return String.valueOf(obj);
+		} else if (DataType.Double == type) {
+			return String.valueOf(obj);
+		} else if (DataType.Boolean == type) {
+			return String.valueOf(obj);
+		} else if (DataType.Date == type) {
+			Date date = null;
+
+			if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Date) {
+				date = (Date) obj;
+			}
+
+			if (date != null) {
+				return Util.DataTimeToString(date);
+			}
+		}
+
+		return String.valueOf(obj);
+	}
+
+	public boolean objectToBoolean(Object obj) {
+		if (obj == null) {
+			return false;
+		}
+
+		if (DataType.String == type) {
+			return Util.stringToBoolean(String.valueOf(obj));
+		} else if (DataType.Boolean == type) {
+			return (Boolean) obj;
+		}
+
+		return false;
+	}
+
+	public Integer objectToInteger(Object obj) {
+		if (obj == null) {
+			return null;
+		}
+
+		if (DataType.String == type) {
+			return Integer.valueOf((String) obj);
+		}
+		else if (DataType.Int == type) {
+			try {
+				return (Integer) obj;
+			}
+			catch (Exception e) {
+				return Integer.valueOf(String.valueOf(obj));
+			}
+		} 
+		else if (DataType.Double == type) {
+			return ((Double) obj).intValue();
+		} 
+		else if (DataType.Decimal == type) {
+			return ((BigDecimal) obj).intValue();
+		} 
+		else {
+			return null;
+		}
+	}
+	
+	public BigDecimal objectToBigDecimal(Object obj) {
+		if (obj == null) {
+			return null;
+		}
+
+		if (DataType.String == type) {
+			return BigDecimal.valueOf(Double.valueOf((String) obj));
+		}
+		else if (DataType.Int == type) {
+			return BigDecimal.valueOf((Integer) obj);
+		} 
+		else if (DataType.Double == type) {
+			return BigDecimal.valueOf((Double) obj);
+		} 
+		else if (DataType.Decimal == type) {
+			return (BigDecimal) obj;
+		} 
+		else {
+			return null;
+		}
+	}
+
+	public Date objectToDate(Object obj) throws ParseException {
+		if (obj == null) {
+			return null;
+		}
+
+		if (obj instanceof Timestamp) {
+			Timestamp value = (Timestamp) obj;
+			return new Date(value.getTime());
+		}
+
+		if (obj instanceof Date) {
+			return (Date) obj;
+		}
+
+		if (obj instanceof String) {
+			String value = (String) obj;
+			return Util.StringToDate(value);
+		}
+
+		return null;
+	}
+
+	public String objectToSchemaString(Object obj) throws Exception {
+		if (obj == null) {
+			return null;
+		}
+
+		if (DataType.String == type) {
+			return "\"" + obj.toString() + "\"";
+		} else if (DataType.Int == type) {
+			return obj.toString();
+		} else if (DataType.Double == type) {
+			return obj.toString();
+		} else if (DataType.Boolean == type) {
+			Boolean bool = (Boolean) obj;
+			return String.valueOf(bool);
+		} else if (DataType.Date == type) {
+			Date date = null;
+
+			if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Date) {
+				date = (Date) obj;
+			}
+
+			if (date != null) {
+				return "\"" + Util.DataTimeToString(date) + "\"";
+			}
+
+			return "\"" + obj.toString() + "\"";
+		}
+
+		return String.valueOf(obj);
+	}
+
+	public String objectToJSONSString(Object obj) throws SQLException {
+		if (obj == null) {
+			return "null";
+		}
+
+		if (DataType.String == type) {
+			return "\"" + obj.toString().replace("\\", "/") + "\"";
+		} else if (DataType.Int == type) {
+			return obj.toString();
+		} else if (DataType.Double == type) {
+			return obj.toString();
+		} else if (DataType.Decimal == type) {
+			return obj.toString();
+		} else if (DataType.Boolean == type) {
+			Boolean bool = (Boolean) obj;
+			return String.valueOf(bool);
+		} else if (DataType.Date == type) {
+			Date date = null;
+
+			if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Date) {
+				date = (Date) obj;
+			}
+
+			if (date != null) {
+				return "\"" + Util.DataTimeToString(date) + "\"";
+			}
+		}
+
+		return "\"" + obj.toString() + "\"";
+	}
+
+	public String objectToSQLString(Object obj) throws Exception {
+		if (obj == null) {
+			return "null";
+		}
+
+		if (DataType.String == type) {
+			return "'" + obj.toString() + "'";
+		} else if (DataType.Int == type) {
+			return obj.toString();
+		} else if (DataType.Double == type) {
+			return obj.toString();
+		} else if (DataType.Boolean == type) {
+			Boolean bool = (Boolean) obj;
+			return String.valueOf(bool);
+		} else if (DataType.Date == type) {
+			Date date = null;
+
+			if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Timestamp) {
+				Timestamp timestamp = (Timestamp) obj;
+				date = new Date(timestamp.getTime());
+			} else if (obj instanceof Date) {
+				date = (Date) obj;
+			} else if (obj instanceof String) {
+				date = Util.StringToDate((String) obj);
+			}
+
+			if (date != null) {
+				return Util.newDBDateString(date);
+			}
+		}
+
+		return "'" + obj.toString() + "'";
+	}
+
+	public Object stringToObject(String value) throws ParseException {
+		if (Util.isEmptyStr(value)) {
+			return null;
+		}
+
+		if (DataType.String == type) {
+			return value;
+		} else if (DataType.Int == type) {
+			return Integer.valueOf(value);
+		} else if (DataType.Double == type) {
+			return Double.valueOf(value);
+		} else if (DataType.Date == type) {
+			return Util.StringToDate(value);
+		}
+
+		return value;
+	}
+
+	public void setValueToStatement(Object obj, PreparedStatement stmt, int paramIdx) throws SQLException {
+		stmt.setObject(paramIdx, obj, sqlType);
+	}
+
+}
diff --git a/src/frame/data/meta/IFieldReader.java b/src/frame/data/meta/IFieldReader.java
new file mode 100644
index 0000000..042d938
--- /dev/null
+++ b/src/frame/data/meta/IFieldReader.java
@@ -0,0 +1,20 @@
+package frame.data.meta;
+
+import java.sql.SQLException;
+
+
+public interface IFieldReader {
+
+	boolean next() throws SQLException;
+
+	String getFieldName() throws SQLException;
+
+	int getFieldType() throws SQLException;
+
+	int getFieldLength() throws SQLException;
+
+	int getNullable() throws SQLException;
+
+	void first();
+
+}
diff --git a/src/frame/data/meta/IMetaDataLoader.java b/src/frame/data/meta/IMetaDataLoader.java
new file mode 100644
index 0000000..b0b15a1
--- /dev/null
+++ b/src/frame/data/meta/IMetaDataLoader.java
@@ -0,0 +1,11 @@
+package frame.data.meta;
+
+import java.sql.ResultSetMetaData;
+
+public interface IMetaDataLoader {
+
+	String getTableName();
+	
+	void load(ResultSetMetaData metaData) throws Exception ;
+	
+}
diff --git a/src/frame/data/meta/MetaContainer.java b/src/frame/data/meta/MetaContainer.java
new file mode 100644
index 0000000..feb657d
--- /dev/null
+++ b/src/frame/data/meta/MetaContainer.java
@@ -0,0 +1,52 @@
+package frame.data.meta;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MetaContainer {
+
+	private static MetaContainer instance;
+	private Map<String, EntityMeta> metaMap;
+	
+	
+	private MetaContainer() {
+		metaMap = new HashMap<String, EntityMeta>();
+	}
+	
+	public static synchronized MetaContainer getInstance() {
+		if (instance == null) {
+			instance = new MetaContainer();
+		}
+		
+		return instance;
+	}
+	
+	public static EntityMeta get(String entityName) throws Exception {
+		return instance.doGet(entityName, false);
+	}
+	
+	public static EntityMeta get(String entityName, boolean refresh) throws Exception {
+		return instance.doGet(entityName, refresh);
+	}
+
+	public EntityMeta doGet(String tableName, boolean refresh) throws Exception {
+		if (tableName == null) {
+			return null;
+		}
+		
+		tableName = tableName.toLowerCase();
+		
+		EntityMeta meta = metaMap.get(tableName);
+		
+		if (refresh || meta == null) {
+			MetaDataLoader metaDataLoader = new MetaDataLoader(tableName);
+			EntityMeta newMeta = metaDataLoader.getEntityMeta();
+			
+			metaMap.put(tableName.toLowerCase(), newMeta);
+			meta = newMeta;
+		}
+		
+		return meta;
+	}
+
+}
diff --git a/src/frame/data/meta/MetaDataLoader.java b/src/frame/data/meta/MetaDataLoader.java
new file mode 100644
index 0000000..761a97f
--- /dev/null
+++ b/src/frame/data/meta/MetaDataLoader.java
@@ -0,0 +1,77 @@
+package frame.data.meta;
+
+import java.sql.Connection;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import frame.persist.SQLRunner;
+import frame.persist.loader.ResultMetaFieldReader;
+import frame.persist.IMetaDataLoader;
+
+
+public class MetaDataLoader implements IMetaDataLoader {
+	
+	private String tableName;
+	private EntityMeta entityMeta;
+	private String schema;
+	
+	
+	public MetaDataLoader(String table) {
+		tableName = table;
+	}
+
+	public String getTableName() {
+		if (schema != null) {
+			return schema + "." + tableName;
+		}
+		
+		return tableName;
+	}
+
+	public void load(ResultSetMetaData metaData) throws Exception {
+		ResultMetaFieldReader fieldReader = new ResultMetaFieldReader(metaData);
+		entityMeta = new EntityMeta(tableName, fieldReader);
+	}
+
+	public EntityMeta getEntityMeta() throws Exception {
+		return getCoreTable(null);
+	}
+	
+	public EntityMeta getCoreTable(Connection conn) throws Exception {
+		if (entityMeta == null) {
+			synchronized (this) {
+				if (entityMeta == null) {
+					SQLRunner.getTableMetaData(conn, this);
+				}
+			}			
+		}
+
+		return entityMeta;
+	}
+
+	public void setSchema(String schema) {
+		this.schema = schema;
+	}
+
+	public static int[] getFieldIndex(ResultSetMetaData metaData, String[] fieldnames) throws SQLException {
+		ResultMetaFieldReader fieldReader = new ResultMetaFieldReader(metaData);
+		EntityMeta tableMeta = new EntityMeta("anymous", fieldReader);
+		
+		int[] result = new int[fieldnames.length];
+		
+		for (int i = 0; i < fieldnames.length; i++) {
+			String fieldname = fieldnames[i];
+			result[i] = tableMeta.getIndex(fieldname) + 1;
+		}
+		
+		return result;
+	}
+
+	public static int getFieldIndex(ResultSetMetaData metaData, String fieldname) throws SQLException {
+		ResultMetaFieldReader fieldReader = new ResultMetaFieldReader(metaData);
+		EntityMeta tableMeta = new EntityMeta("anymous", fieldReader);
+		
+		return tableMeta.getIndex(fieldname) + 1;
+	}
+	
+}
diff --git a/src/frame/data/reader/CollectionReader.java b/src/frame/data/reader/CollectionReader.java
new file mode 100644
index 0000000..8b9d2a2
--- /dev/null
+++ b/src/frame/data/reader/CollectionReader.java
@@ -0,0 +1,103 @@
+package frame.data.reader;
+
+import java.util.Collection;
+
+import frame.data.convert.Convertor;
+import frame.util.ContentBuilder;
+
+public class CollectionReader extends EntityReader {
+
+	protected IEntityReader valueReader;
+	protected Convertor translator;
+	
+	public CollectionReader(Class<?> clazz) throws Exception {
+		super(clazz);
+	}
+
+	@Override
+	protected void initValueReader(Class<?> dataType) throws Exception {
+		if (translator == null && valueReader == null) {
+			if (Convertor.containsType(dataType)) {
+				translator = Convertor.getInstance(dataType);
+			}
+			else {
+				valueReader = EntityReader.getInstance(dataType);
+			}
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public String getString(Object entity) {
+		Collection<Object> collection = (Collection<Object>) entity;
+		
+		if (collection.isEmpty()) {
+			return "[]";
+		}
+		
+		ContentBuilder result = new ContentBuilder();
+		result.append("[");
+		
+		try {
+			initValueReader(collection.iterator().next().getClass());
+		} catch (Exception e) {
+			return e.getMessage();
+		}
+		
+		for (Object value: collection) {
+			try {
+				if (translator != null) {
+					result.append(translator.toString(value), ", ");
+				}
+				else {
+					result.append(valueReader.getString(value), ", ");
+				}
+			}
+			catch (Exception e) {
+				result.append("error", ",");
+			}
+		}
+		
+		result.append("]");
+		return result.toString();
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public String getJSONString(Object entity) throws Exception {
+		Collection<Object> collection = (Collection<Object>) entity;
+		
+		if (collection.isEmpty()) {
+			return "[]";
+		}
+		
+		ContentBuilder result = new ContentBuilder();
+		result.append("[");
+		
+		try {
+			Class<?> clazz = collection.iterator().next().getClass();
+			initValueReader(clazz);
+		} 
+		catch (Exception e) {
+			return e.getMessage();
+		}
+		
+		for (Object value: collection) {
+			try {
+				if (translator != null) {
+					result.append(translator.toJSONString(value), ", ");
+				}
+				else {
+					result.append(valueReader.getJSONString(value), ", ");
+				}
+			}
+			catch (Exception e) {
+				result.append("error", ",");
+			}
+		}
+		
+		result.append("]");
+		return result.toString();
+	}
+
+}
diff --git a/src/frame/data/reader/EntityReader.java b/src/frame/data/reader/EntityReader.java
new file mode 100644
index 0000000..d3a3d3f
--- /dev/null
+++ b/src/frame/data/reader/EntityReader.java
@@ -0,0 +1,76 @@
+package frame.data.reader;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+public abstract class EntityReader implements IEntityReader {
+
+	protected static Logger logger;
+	protected static Set<String> excludeMethods;
+	protected Class<?> clazz;
+
+	static {
+		logger = Logger.getLogger(ObjectReader.class);
+		createExcludeMethodSet();
+	}
+
+	protected EntityReader(Class<?> clazz) {
+		this.clazz = clazz;
+	}
+
+	public static IEntityReader getInstance(Class<?> clazz) throws Exception {
+
+		if (Collection.class.isAssignableFrom(clazz)) {
+			return new CollectionReader(clazz);
+
+		} else if (Map.class.isAssignableFrom(clazz)) {
+			return new MapReader(clazz);
+
+		} else {
+			return new ObjectReader(clazz);
+		}
+	}
+
+	protected abstract void initValueReader(Class<?> dataType) throws Exception;
+
+	public abstract String getString(Object entity);
+
+	public abstract String getJSONString(Object entity) throws Exception;
+
+	public Class<?> getEntityClass() {
+		return clazz;
+	}
+
+	private static void createExcludeMethodSet() {
+		excludeMethods = new HashSet<String>();
+		excludeMethods.add("getclass");
+		excludeMethods.add("getnames");
+		excludeMethods.add("getsize");
+		excludeMethods.add("containsproperty");
+		excludeMethods.add("loaddata");
+		excludeMethods.add("setdata");
+		excludeMethods.add("setdatastring");
+		excludeMethods.add("getdata");
+		excludeMethods.add("getstring");
+		excludeMethods.add("getjsonstring");
+		excludeMethods.add("getsqlstring");
+		excludeMethods.add("getvalue");
+		excludeMethods.add("getdynamicdata");
+		excludeMethods.add("iterator");
+		excludeMethods.add("tostring");
+		excludeMethods.add("finalize");
+		excludeMethods.add("wait");
+		excludeMethods.add("hashcode");
+		excludeMethods.add("clone");
+		excludeMethods.add("registernatives");
+		excludeMethods.add("equals");
+		excludeMethods.add("notify");
+		excludeMethods.add("notifyall");
+		excludeMethods.add("getinstance");
+	}
+
+}
diff --git a/src/frame/data/reader/EntityReaderContainer.java b/src/frame/data/reader/EntityReaderContainer.java
new file mode 100644
index 0000000..eae6637
--- /dev/null
+++ b/src/frame/data/reader/EntityReaderContainer.java
@@ -0,0 +1,73 @@
+package frame.data.reader;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EntityReaderContainer {
+
+	private static EntityReaderContainer instance;
+	private Map<Class<?>, IEntityReader> items;
+
+	private EntityReaderContainer() {
+		items = new HashMap<Class<?>, IEntityReader>();
+	}
+
+	public static synchronized EntityReaderContainer getInstance() {
+		if (instance == null) {
+			instance = new EntityReaderContainer();
+		}
+
+		return instance;
+	}
+
+	public IEntityReader getEntityReader(Class<?> clazz) throws Exception {
+
+		IEntityReader reader = items.get(clazz);
+
+		if (reader == null) {
+			reader = EntityReader.getInstance(clazz);
+
+			// 淇濊瘉闆嗗悎绫籧lass銆丮ap绫籧lass涓嶅湪items涓�
+			if (reader instanceof CollectionReader || reader instanceof MapReader) {
+				return reader;
+			}
+			items.put(clazz, reader);
+		}
+
+		return reader;
+	}
+
+	public ObjectReader getObjectReader(Class<?> clazz) throws Exception {
+		IEntityReader reader = items.get(clazz);
+
+		if (reader == null) {
+			reader = new ObjectReader(clazz);
+			items.put(clazz, reader);
+		}
+
+		return (ObjectReader) reader;
+	}
+
+	public MapReader getMapReader(Class<?> clazz) throws Exception {
+		IEntityReader reader = items.get(clazz);
+
+		if (reader == null) {
+			reader = new MapReader(clazz);
+			items.put(clazz, reader);
+		}
+
+		return (MapReader) reader;
+	}
+
+	public CollectionReader getCollectionReader(Class<?> clazz) throws Exception {
+		IEntityReader reader = items.get(clazz);
+
+		if (reader == null) {
+			reader = new CollectionReader(clazz);
+			items.put(clazz, reader);
+		}
+
+		return (CollectionReader) reader;
+	}
+
+}
diff --git a/src/frame/data/reader/IEntityReader.java b/src/frame/data/reader/IEntityReader.java
new file mode 100644
index 0000000..7265a90
--- /dev/null
+++ b/src/frame/data/reader/IEntityReader.java
@@ -0,0 +1,9 @@
+package frame.data.reader;
+
+public interface IEntityReader {
+
+	String getString(Object entity);
+	
+	String getJSONString(Object entity) throws Exception;
+	
+}
diff --git a/src/frame/data/reader/MapReader.java b/src/frame/data/reader/MapReader.java
new file mode 100644
index 0000000..f916c2c
--- /dev/null
+++ b/src/frame/data/reader/MapReader.java
@@ -0,0 +1,113 @@
+package frame.data.reader;
+
+import java.util.Map;
+import java.util.Set;
+
+import frame.data.convert.Convertor;
+import frame.util.ContentBuilder;
+
+
+public class MapReader extends EntityReader {
+
+	protected Convertor translator;
+	protected IEntityReader valueReader;
+	
+	public MapReader(Class<?> clazz) throws Exception {
+		super(clazz);
+	}
+
+	@Override
+	protected void initValueReader(Class<?> dataType) throws Exception {
+		if (translator == null && valueReader == null) {
+			if (Convertor.containsType(dataType)) {
+				translator = Convertor.getInstance(dataType);
+			}
+			else {
+				valueReader = EntityReader.getInstance(dataType);
+			}
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public String getString(Object entity) {
+		try {
+			Map<Object, Object> map = (Map<Object, Object>) entity;		
+			
+			if (map.isEmpty()) {
+				return "[]";
+			}
+			
+			ContentBuilder result = new ContentBuilder();
+			result.append("[");
+			
+			Set<Object> keys = map.keySet();
+
+			initValueReader(keys.iterator().next().getClass());
+		
+			for (Object key: keys) {
+				Object obj = map.get(key);
+				
+				try {
+					if (translator != null) {
+						result.append(key, ",").append(":").append(translator.toString(obj));
+					}
+					else {
+						result.append(key, ",").append(":").append(valueReader.getString(obj));
+					}					
+				}
+				catch (Exception e) {
+					result.append(key, ",").append(":error");
+				}
+			}
+			
+			result.append("]");
+			return result.toString();
+		} 
+		catch (Exception e) {
+			return e.getMessage();
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public String getJSONString(Object entity) throws Exception {
+		Map<Object, Object> map = (Map<Object, Object>) entity;
+		
+		if (map.isEmpty()) {
+			return "{}";
+		}
+		
+		ContentBuilder result = new ContentBuilder();
+		result.append("{");
+		
+		Set<Object> keys = map.keySet();
+		
+		try {
+			Class<?> clazz = keys.iterator().next().getClass();
+			initValueReader(clazz);
+		} catch (Exception e) {
+			return e.getMessage();
+		}
+		
+		for (Object key: keys) {
+			Object obj = map.get(key);
+			
+			try {
+				if (translator != null) {
+					result.append("\"", ",").append(key).append("\":").append(translator.toJSONString(obj));
+				}
+				else {
+					result.append("\"", ",").append(key).append("\":").append(valueReader.getJSONString(obj));
+				}				
+			}
+			catch (Exception e) {
+				result.append("\"", ",").append(key).append("\":\"error\"");
+			}
+		}
+		
+		result.append("}");
+		return result.toString();
+	}
+
+}
diff --git a/src/frame/data/reader/ObjectPropertyRecorder.java b/src/frame/data/reader/ObjectPropertyRecorder.java
new file mode 100644
index 0000000..36b8ba6
--- /dev/null
+++ b/src/frame/data/reader/ObjectPropertyRecorder.java
@@ -0,0 +1,95 @@
+package frame.data.reader;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import frame.data.convert.Convertor;
+
+public class ObjectPropertyRecorder {
+	
+	private List<String> nameList;
+	private List<String> lowerNameList;
+	private Map<String, Integer> nameMap;
+	private Map<String, PropertyReader> propertyReaderMap;
+	private List<PropertyReader> propertyReaderList;
+	
+	
+	public ObjectPropertyRecorder() {
+		nameList = new ArrayList<String>();
+		lowerNameList = new ArrayList<String>();
+		nameMap = new HashMap<String, Integer>();
+		propertyReaderMap = new HashMap<String, PropertyReader>();
+		propertyReaderList = new LinkedList<PropertyReader>();
+	}
+
+	public void addGetMethod(String name, Method method) throws Exception {
+		Class<?> returnType = method.getReturnType();
+		String lower = name.toLowerCase();
+		
+		PropertyReader propertyReader = propertyReaderMap.get(lower);
+		
+		if (propertyReader == null) {
+			nameMap.put(lower, nameList.size());
+			
+			nameList.add(name);
+			lowerNameList.add(lower);
+			
+			propertyReader = new PropertyReader(name, returnType);
+			
+			propertyReaderList.add(propertyReader);	
+			propertyReaderMap.put(lower, propertyReader);
+		}
+		
+		propertyReader.setGetMethod(method);			
+	}
+	
+	public void addSetMethod(String name, Method method) throws Exception {
+		Class<?> paramType = method.getParameterTypes()[0];
+		if (!Convertor.containsType(paramType)) {
+			return;
+		}
+		
+		String lower = name.toLowerCase();
+		
+		PropertyReader propertyReader = propertyReaderMap.get(lower);
+		
+		if (propertyReader == null) {
+			nameMap.put(lower, nameList.size());
+			
+			nameList.add(name);
+			lowerNameList.add(lower);
+			
+			propertyReader = new PropertyReader(name, paramType);
+			
+			propertyReaderList.add(propertyReader);	
+			propertyReaderMap.put(lower, propertyReader);
+		}
+		
+		propertyReader.setSetMethod(method);			
+	}
+	
+	public PropertyReader[] getPropertyReaderArray() {
+		PropertyReader[] result = new PropertyReader[propertyReaderList.size()];
+		result = propertyReaderList.toArray(result);
+		
+		return result;
+	}
+
+	public String[] getNameArray() {
+		String[] result = new String[nameList.size()];
+		return nameList.toArray(result);
+	}
+
+	public String[] getLowerNameArray() {
+		String[] result = new String[lowerNameList.size()];
+		return lowerNameList.toArray(result);
+	}
+
+	public Map<String, Integer> getNameMap() {
+		return nameMap;
+	}
+}
diff --git a/src/frame/data/reader/ObjectReader.java b/src/frame/data/reader/ObjectReader.java
new file mode 100644
index 0000000..16214a4
--- /dev/null
+++ b/src/frame/data/reader/ObjectReader.java
@@ -0,0 +1,431 @@
+package frame.data.reader;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+
+import frame.data.Entity;
+import frame.data.Variant;
+import frame.util.ContentBuilder;
+
+
+public class ObjectReader extends EntityReader implements Iterable<PropertyReader> {
+
+	private int size;
+	private String[] names;
+	private String[] lowerNames;
+	private Map<String, Integer> nameMap;
+	private PropertyReader[] propertyReaderArray;
+	
+	public ObjectReader(Class<?> clazz) throws Exception {
+		super(clazz);
+		initValueReader(clazz);
+	}
+	
+	@Override
+	protected void initValueReader(Class<?> dataType) throws Exception {
+		ObjectPropertyRecorder propertyRecorder = new ObjectPropertyRecorder();
+		
+		Method[] methods;
+		String methodName;
+		String property;
+		char first;
+		
+		while (dataType != null) {
+			//鑷繁鐨勬墍鏈夋柟娉�(鍚鏈�)
+			methods = dataType.getDeclaredMethods();
+		
+			for (Method method: methods) {
+				if (method.isBridge()) {
+					continue;
+				}
+				
+				methodName = method.getName();
+				Class<?>[] params = method.getParameterTypes();
+				
+				if (excludeMethods.contains(methodName.toLowerCase())) {
+					continue;
+				}
+				
+				if (methodName.startsWith("get")) {
+					if (params.length > 0) {
+						continue;
+					}
+					
+					Class<?> returnTypeClass = method.getReturnType();
+					if (Enum.class.isAssignableFrom(returnTypeClass)) {
+						continue;
+					}
+					
+					property = methodName.substring(3); 
+					first = property.charAt(0);
+					property = Character.toLowerCase(first) + property.substring(1);
+					
+					propertyRecorder.addGetMethod(property, method);
+				}
+				else if (methodName.startsWith("is")) {
+					if (params.length > 0) {
+						continue;
+					}
+					
+					property = methodName.substring(2); 
+					first = property.charAt(0);
+					property = Character.toLowerCase(first) + property.substring(1);
+					
+					propertyRecorder.addGetMethod(property, method);
+				}
+				else if (methodName.startsWith("set")) {
+					if (params.length > 1) {
+						continue;
+					}
+					
+					property = methodName.substring(3); 
+					first = property.charAt(0);
+					property = Character.toLowerCase(first) + property.substring(1);
+					
+					propertyRecorder.addSetMethod(property, method);
+				}
+			}
+			
+			dataType = dataType.getSuperclass();
+		}
+	
+		names = propertyRecorder.getNameArray();
+		lowerNames = propertyRecorder.getLowerNameArray();
+		nameMap = propertyRecorder.getNameMap();
+		propertyReaderArray = propertyRecorder.getPropertyReaderArray();
+		size = propertyReaderArray.length;		
+	}
+
+	@Override
+	public String getString(Object entity) {
+		ContentBuilder result = new ContentBuilder();
+		result.append("[");
+		
+		for (int i = 0; i < size; i++) {
+			String value;
+			try {
+				value = propertyReaderArray[i].getJSONString(entity);
+			} catch (Exception e) {
+				value = "error";
+			}
+			result.append(lowerNames[i], ",").append(":").append(value);
+		}
+		
+		result.append("]");
+		return result.toString();
+	}
+
+	@Override
+	public String getJSONString(Object entity) throws Exception {
+		ContentBuilder result = new ContentBuilder();
+		result.append("{");
+		
+		result.setEmpty(true);
+		
+		for (int i = 0; i < size; i++) {
+			String value = propertyReaderArray[i].getJSONString(entity);
+			result.append("\"", ",").append(lowerNames[i]).append("\":").append(value);
+		}
+		
+		result.append("}");
+		return result.toString();
+	}
+
+	public String[] getNames() {
+		return names;
+	}
+	
+	public String[] getLowerNames() {
+		return lowerNames;
+	}
+	
+	public boolean containsProperty(String name) {
+		if (name == null) {
+			return false;
+		}
+		
+		return nameMap.containsKey(name.toLowerCase());
+	}
+	
+	public int size() {
+		return size;
+	}
+	
+	public Integer getIndexByName(String name) {
+		if (name == null) {
+			return null;
+		}
+		
+		return nameMap.get(name.toLowerCase());
+	}
+
+	public PropertyReader getPropertyReader(String name) {
+		if (name == null) {
+			return null;
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			return null;			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader;
+	}
+	
+	public PropertyReader getPropertyReader(int idx) {
+		return propertyReaderArray[idx];
+	}
+	
+	public void setData(String name, Object value, Object entity) throws Exception {
+		if (name == null) {
+			return;
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("set data error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		propertyReader.setData(entity, value);
+	}
+	
+	public void setData(int idx, Object value, Object entity) throws Exception {
+		if (idx >= 0 && idx < size) {
+			PropertyReader propertyReader = propertyReaderArray[idx];
+			propertyReader.setData(entity, value);
+		}
+	}
+	
+	public void setDataString(String name, String value, Object entity) throws Exception {
+		if (name == null) {
+			return;
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("set data string error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		propertyReader.setDataString(entity, value);
+	}
+	
+	public void setDataString(int idx, String value, Object entity) throws Exception {
+		if (idx >= 0 && idx < size) {
+			PropertyReader propertyReader = propertyReaderArray[idx];
+			propertyReader.setDataString(entity, value);
+		}
+	}
+	
+	public Object getData(String name, Object entity) throws Exception {
+		if (name == null) {
+			return null;
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			return null;	
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.getObject(entity);
+	}
+	
+	public Object getData(int propertyIndex, Object entity) throws Exception {
+		if (propertyIndex >= 0 && propertyIndex < size) {
+			PropertyReader propertyReader = propertyReaderArray[propertyIndex];
+			return propertyReader.getObject(entity);
+		}
+		else {
+			throw new Exception("get data error: index " + propertyIndex + " out of 0~" + size);
+		}
+	}
+	
+	public String getString(String name, Object entity) {
+		if (name == null) {
+			return "error";
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			return "error";			
+		}
+		
+		try {
+			PropertyReader propertyReader = propertyReaderArray[idx];
+			return propertyReader.getString(entity);
+		}
+		catch (Exception e) {
+			return "error";
+		}
+	}
+	
+	public String getString(int index, Object entity) {
+		if (index >= 0 && index < size) {
+			try {
+				PropertyReader propertyReader = propertyReaderArray[index];
+				return propertyReader.getString(entity);
+			}
+			catch (Exception e) {
+				return "error";
+			}
+		}
+		else {
+			return "error";
+		}
+	}
+	
+	public String getJSONString(String name, Object entity) throws Exception {
+		if (name == null) {
+			return "error";
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			return "error";			
+		}
+		
+		try {
+			PropertyReader propertyReader = propertyReaderArray[idx];
+			return propertyReader.getJSONString(entity);
+		}
+		catch (Exception e) {
+			return "error";
+		}
+	}
+
+	public String getJSONString(int index, Object entity) throws Exception {
+		if (index >= 0 && index < size) {
+			try {
+				PropertyReader propertyReader = propertyReaderArray[index];
+				return propertyReader.getJSONString(entity);
+			}
+			catch (Exception e) {
+				return "\"error\"";
+			}
+		}
+		else {
+			return "\"error\"";
+		}
+	}
+	
+	public String getSQLString(String name, Object entity) throws Exception {
+		if (name == null) {
+			throw new Exception("get sql string error: empty name");
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("get sql string error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.getSQLString(entity);
+	}
+	
+	public String getSQLString(int propertyIndex, Object entity) throws Exception {
+		if (propertyIndex >= 0 && propertyIndex < size) {
+			PropertyReader propertyReader = propertyReaderArray[propertyIndex];
+			return propertyReader.getSQLString(entity);
+		}
+		else {
+			throw new Exception("get json string error: index " + propertyIndex + " out of 0~" + size);
+		}
+	}
+	
+	public Integer getInteger(String name, Entity entity) throws Exception {
+		if (name == null) {
+			throw new Exception("get integer error: empty name");
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("get integer error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.getInteger(entity);
+	}
+
+	public Double getDouble(String name, Entity entity) throws Exception {
+		if (name == null) {
+			throw new Exception("get double error: empty name");
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("get integer error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.getDouble(entity);
+	}
+
+	public Boolean getBoolean(String name, Entity entity) throws Exception {
+		if (name == null) {
+			throw new Exception("get boolean error: empty name");
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("get integer error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.getBoolean(entity);
+	}
+
+	public Date getDate(String name, Entity entity) throws Exception {
+		if (name == null) {
+			throw new Exception("get date error: empty name");
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("get integer error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.getDate(entity);
+	}
+	
+	public Variant loadToVariant(String name, String value) throws Exception {
+		if (name == null) {
+			throw new Exception("load to variant error: empty name");
+		}
+		
+		Integer idx = nameMap.get(name.toLowerCase());
+		
+		if (idx == null) {
+			throw new Exception("load to variant error: " + name + " not exist");			
+		}
+		
+		PropertyReader propertyReader = propertyReaderArray[idx];
+		return propertyReader.loadToVariant(value);
+	}
+	
+	public String getPropertyName(int idx) {
+		return names[idx];
+	}
+	
+	@Override
+	public Iterator<PropertyReader> iterator() {
+		return new PropertyIterator(this);
+	}
+
+}
diff --git a/src/frame/data/reader/PropertyReader.java b/src/frame/data/reader/PropertyReader.java
new file mode 100644
index 0000000..0d2adb4
--- /dev/null
+++ b/src/frame/data/reader/PropertyReader.java
@@ -0,0 +1,36 @@
+package frame.data.reader;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import frame.data.Variant;
+
+public class PropertyReader {
+
+	private File file;
+	private Properties properties;
+	
+	public PropertyReader(File file) throws IOException {
+		this.file = file;
+		load();
+	}
+
+	public Variant get(String name) {
+		String value = properties.getProperty(name);
+		return new Variant(value);
+	}
+	
+	private void load() throws IOException {
+		properties = new Properties();
+		
+		FileInputStream inputStream = new FileInputStream(file);
+		try {
+			properties.load(inputStream);
+		}
+		finally {
+			inputStream.close();
+		}
+	}
+}
diff --git a/src/frame/expression/Expression.java b/src/frame/expression/Expression.java
new file mode 100644
index 0000000..230c8bb
--- /dev/null
+++ b/src/frame/expression/Expression.java
@@ -0,0 +1,154 @@
+package frame.expression;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import frame.util.Util;
+
+public class Expression implements Iterable<VariantSegment>, IVariantParseListener, IExpression {
+	
+	protected static Logger logger;
+	protected List<Segment> segments;
+	protected VariantList variantList;
+	
+	static {
+		logger = Logger.getLogger(Expression.class);
+	}
+	
+	public Expression(String string) throws Exception {
+		this(string, 0);
+	}
+	
+	public Expression(String string, int size) throws Exception {
+		this(size);
+		
+		VariantParser parser = new VariantParser(this);
+		parser.parse(string);
+	}
+
+	private Expression(int size) throws Exception {
+		if (size <= 0) {
+			size = 4;
+		}
+		
+		segments = new ArrayList<Segment>(size);
+		variantList = new VariantList();
+	}
+	
+	public Expression newInstance() throws Exception {
+		int size = segments.size();
+		Expression instance = new Expression(size);
+		
+		Segment segment;
+		VariantSegment param;
+		
+		for (int i = 0; i < size; i++) {
+			segment = segments.get(i);
+			
+			if (segment instanceof VariantSegment) {
+				param = (VariantSegment) segment;
+				String name = param.getName();
+				
+				if (instance.variantList.contains(param.getName())) {
+					instance.segments.add(instance.variantList.get(name));
+				}
+				else {
+					segment = segment.newInstance();
+					instance.segments.add(segment);
+					instance.variantList.add(name, (VariantSegment) segment);
+				}
+			}
+			else {
+				segment = segment.newInstance();
+				instance.segments.add(segment);
+			}
+		}
+		
+		return instance;
+	}
+	
+	public String tryGetString() throws Exception {
+		for (VariantSegment variant : variantList) {
+			if (variant.isEmpty()) {
+				throw new Exception("empty sql param: " + variant.getName());
+			}
+		}
+		
+		return getString();
+	}
+	
+	public String getString() {
+		StringBuilder result = new StringBuilder();
+		
+		int n = segments.size();
+		Segment segment;
+		String value;
+		
+		for (int i = 0; i < n; i++) {
+			segment = segments.get(i);
+			value = segment.getValueString();
+			
+			result.append(value);
+		}
+		
+		return result.toString();
+	}
+	
+	@Override
+	public void onSegment(String value) {
+		if (Util.isEmptyStr(value)) {
+			return;
+		}
+		
+		Segment segment = new StringSegment(value);
+		segments.add(segment);
+	}
+
+	@Override
+	public void addVariant(String name) throws Exception {
+		if (Util.isEmptyStr(name)) {
+			return;
+		}
+		
+		if (variantList.contains(name)) {
+			VariantSegment segment = variantList.get(name);
+			segments.add(segment);
+		}
+		else {
+			VariantSegment segment = new VariantSegment(name);
+			segments.add(segment);
+			variantList.add(name, segment);
+		}	
+	}
+	
+	public VariantSegment getVariant(String name) {
+		if (Util.isEmptyStr(name)) {
+			return null;
+		}
+		
+		return variantList.get(name);
+	}
+
+	public Iterator<VariantSegment> iterator() {
+		return variantList.getItemList().iterator();
+	}
+
+	@Override
+	public VariantList getVariantList() {
+		return variantList;
+	}
+
+	public boolean isVariantEmpty() {
+		return variantList.isEmpty();
+	}
+	
+	public void clearVariantValues() {
+		for (VariantSegment variant: variantList) {
+			variant.clearValue();
+		}		
+	}
+
+}
diff --git a/src/frame/expression/GlobalVariant.java b/src/frame/expression/GlobalVariant.java
new file mode 100644
index 0000000..951a161
--- /dev/null
+++ b/src/frame/expression/GlobalVariant.java
@@ -0,0 +1,131 @@
+package frame.expression;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import frame.util.Util;
+
+public class GlobalVariant {
+
+	private static Object lock = new Object();
+	private static GlobalVariant instance;
+	private Map<String, IVariantRequestListener> listenerMap;
+	
+	private GlobalVariant() throws VariantExistsException {
+		listenerMap = new HashMap<String, IVariantRequestListener>();
+	}
+	
+	public static GlobalVariant getInstance() {
+		if (instance == null) {
+			synchronized(lock) {
+				try {
+					if (instance == null) {
+						instance = new GlobalVariant();
+						GlobalVariantProvider provider = new GlobalVariantProvider();
+						GlobalVariant.regist(provider);
+					}
+				}
+				catch(Exception e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		
+		return instance;
+	}
+	
+	public static void regist(IVariantRequestListener listener) throws VariantExistsException {
+		GlobalVariant service = getInstance();
+		
+		List<String> variantNames = listener.getVariantNames();
+		
+		if (variantNames == null) {
+			return;
+		}
+		
+		for (String name: variantNames) {
+			if (name == null) {
+				continue;
+			}
+			
+			String lower = name.toLowerCase();
+			
+			if (service.listenerMap.containsKey(lower)) {
+				throw new VariantExistsException(name);
+			}
+			
+			service.listenerMap.put(lower, listener);
+		}
+	}
+	
+	public static String getStringValue(String name) throws Exception {
+		return getStringValue(name, null);
+	}
+		
+	public static String getStringValue(String name, VariantRequestParams params) throws Exception {
+		GlobalVariant service = getInstance();
+		
+		if (name == null) {
+			return null;
+		}
+		
+		String lower = name.toLowerCase();
+		
+		IVariantRequestListener listener = service.listenerMap.get(lower);
+		
+		if (listener == null) {
+			new VariantNotFoundException(name);
+		}
+		
+		return listener.getStringValue(lower, params);
+	}
+	
+	public static class GlobalVariantProvider implements IVariantRequestListener {
+		
+		private List<String> variantNames;
+		
+		public GlobalVariantProvider() {
+			variantNames = new ArrayList<String>();
+			initVariantNames();
+		}
+		
+		@Override
+		public String getStringValue(String name, VariantRequestParams params) {
+			if ("guid".equals(name)) {
+				return Util.newShortGUID();
+			}
+			else if ("newDate".equals(name)) {
+				return Util.newDateStr();
+			}
+			else if ("newDateTime".equals(name)) {
+				return Util.newDateTimeStr();
+			}
+			else if ("current.year".equals(name)) {
+				Calendar calendar = Calendar.getInstance();
+				return String.valueOf(calendar.get(Calendar.YEAR));
+			}
+			else if ("current.month".equals(name)) {
+				Calendar calendar = Calendar.getInstance();
+				return String.valueOf(calendar.get(Calendar.MONTH) + 1);
+			}
+			
+			return null;			
+		}
+
+		@Override
+		public List<String> getVariantNames() {
+			return variantNames;
+		}
+		
+		public void initVariantNames() {
+			variantNames.add("guid");
+			variantNames.add("newDate");
+			variantNames.add("newDateTime");
+			variantNames.add("current.year");
+			variantNames.add("current.month");
+		}
+	}
+}
diff --git a/src/frame/expression/IExpression.java b/src/frame/expression/IExpression.java
new file mode 100644
index 0000000..325d115
--- /dev/null
+++ b/src/frame/expression/IExpression.java
@@ -0,0 +1,8 @@
+package frame.expression;
+
+
+public interface IExpression {
+
+	VariantList getVariantList();
+
+}
diff --git a/src/frame/expression/IVariantParseListener.java b/src/frame/expression/IVariantParseListener.java
new file mode 100644
index 0000000..baf97bc
--- /dev/null
+++ b/src/frame/expression/IVariantParseListener.java
@@ -0,0 +1,9 @@
+package frame.expression;
+
+public interface IVariantParseListener {
+
+	void onSegment(String segment);
+
+	void addVariant(String variant) throws Exception;
+
+}
diff --git a/src/frame/expression/IVariantRequestListener.java b/src/frame/expression/IVariantRequestListener.java
new file mode 100644
index 0000000..8e003fd
--- /dev/null
+++ b/src/frame/expression/IVariantRequestListener.java
@@ -0,0 +1,11 @@
+package frame.expression;
+
+import java.util.List;
+
+public interface IVariantRequestListener {
+
+	public List<String> getVariantNames();
+
+	public String getStringValue(String name, VariantRequestParams params) throws Exception;
+	
+}
diff --git a/src/frame/expression/Segment.java b/src/frame/expression/Segment.java
new file mode 100644
index 0000000..0a3db08
--- /dev/null
+++ b/src/frame/expression/Segment.java
@@ -0,0 +1,18 @@
+package frame.expression;
+
+import org.apache.log4j.Logger;
+
+
+public abstract class Segment {
+
+	protected static Logger logger;
+	
+	static {
+		logger = Logger.getLogger(Segment.class);
+	}
+	
+	abstract public String getValueString();
+	
+	abstract public Segment newInstance();
+	
+}
diff --git a/src/frame/expression/StringSegment.java b/src/frame/expression/StringSegment.java
new file mode 100644
index 0000000..b43929d
--- /dev/null
+++ b/src/frame/expression/StringSegment.java
@@ -0,0 +1,26 @@
+package frame.expression;
+
+
+public class StringSegment extends Segment {
+
+	private String value;
+	
+	public StringSegment(String value) {
+		this.value = value;
+	}
+	
+	@Override
+	public String getValueString() {
+		return value;
+	}
+
+	public String toString() {
+		return value;
+	}
+
+	@Override
+	public Segment newInstance() {
+		return new StringSegment(value);
+	}
+
+}
diff --git a/src/frame/expression/VariantContext.java b/src/frame/expression/VariantContext.java
new file mode 100644
index 0000000..72fa9ea
--- /dev/null
+++ b/src/frame/expression/VariantContext.java
@@ -0,0 +1,70 @@
+package frame.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public abstract class VariantContext implements IVariantRequestListener {
+
+	private List<VariantContext> linkedContextList;
+	
+	public VariantContext() {
+		linkedContextList = new ArrayList<VariantContext>();
+	}
+	
+	public void setParametersTo(IExpression expression) throws Exception {
+		doSetParametersTo(expression, true);
+	}
+	
+	protected void doSetParametersTo(IExpression expression, boolean queryGlabal) throws Exception {
+		VariantList paramList = expression.getVariantList();
+		
+		//1. on local
+		for (VariantSegment variant: paramList) {
+			if (!variant.isEmpty()) {
+				continue;
+			}
+			
+			String name = variant.getName();
+			String value = getStringValue(name, null);
+
+			if (value != null) {
+				variant.setValue(value);
+			}
+		}
+		
+		//2. on linked
+		for (VariantContext linked: linkedContextList) {
+			linked.doSetParametersTo(expression, false);
+		}
+		
+		//3.
+		if (queryGlabal) {
+			for (VariantSegment variant: paramList) {
+				if (!variant.isEmpty()) {
+					continue;
+				}
+				
+				String name = variant.getName();
+				String value = GlobalVariant.getStringValue(name, null);
+
+				if (value != null) {
+					variant.setValue(value);
+				}
+			}			
+		}
+	}
+
+	@Override
+	public List<String> getVariantNames() {
+		return null;
+	}
+
+	@Override
+	public abstract String getStringValue(String name, VariantRequestParams params) throws Exception;
+	
+	public void linkContext(VariantContext context) {
+		linkedContextList.add(context);
+	}
+	
+}
diff --git a/src/frame/expression/VariantExistsException.java b/src/frame/expression/VariantExistsException.java
new file mode 100644
index 0000000..ca8dd49
--- /dev/null
+++ b/src/frame/expression/VariantExistsException.java
@@ -0,0 +1,11 @@
+package frame.expression;
+
+public class VariantExistsException extends Exception {
+
+	private static final long serialVersionUID = 6370169285699904127L;
+	
+	public VariantExistsException(String name) {
+		super("variant has exists: " + name);
+	}
+
+}
diff --git a/src/frame/expression/VariantList.java b/src/frame/expression/VariantList.java
new file mode 100644
index 0000000..9c09580
--- /dev/null
+++ b/src/frame/expression/VariantList.java
@@ -0,0 +1,12 @@
+package frame.expression;
+
+import frame.util.MapList;
+
+public class VariantList extends MapList<VariantSegment>{
+	
+	public void clearValues() {
+		for (VariantSegment param: itemList) {
+			param.clearValue();
+		}
+	}
+}
diff --git a/src/frame/expression/VariantNotFoundException.java b/src/frame/expression/VariantNotFoundException.java
new file mode 100644
index 0000000..826d10f
--- /dev/null
+++ b/src/frame/expression/VariantNotFoundException.java
@@ -0,0 +1,10 @@
+package frame.expression;
+
+public class VariantNotFoundException extends Exception {
+
+	private static final long serialVersionUID = 5270739430116585535L;
+	
+	public VariantNotFoundException(String name) {
+		super("param not found : " + name);
+	}
+}
diff --git a/src/frame/expression/VariantParser.java b/src/frame/expression/VariantParser.java
new file mode 100644
index 0000000..7e53257
--- /dev/null
+++ b/src/frame/expression/VariantParser.java
@@ -0,0 +1,107 @@
+package frame.expression;
+
+public class VariantParser {
+
+	private static char Flag_Variant = '@';
+	private static char Flag_LeftQuote = '{';	
+	private static char Flag_RightQuote = '}';	
+	private IVariantParseListener listener;
+
+	public VariantParser(IVariantParseListener listener) {
+		this.listener = listener;
+	}
+	
+	public void parse(String expression) throws Exception {
+		if (expression == null) {
+			return;
+		}
+		
+		int length = expression.length();
+		
+		String segmentString;
+		int variantLength = 0;		
+		int begin = 0;
+		char curr;
+		
+		for (int i = 0; i < length; i++) {
+			curr = expression.charAt(i);
+			
+			if (isKey(curr)) {
+				if (Flag_LeftQuote != expression.charAt(Math.min(i + 1, length - 1))) {
+					continue;
+				}
+				
+				segmentString = expression.substring(begin, i);
+				onFindSegment(segmentString);
+				
+				variantLength = getVariantLength(expression, i + 1, length);
+				segmentString = expression.substring(i + 2, i + 2 + variantLength);
+				
+				onFindVariant(curr, segmentString);
+				
+				i = i + 2 + variantLength + 1;
+				begin = i;
+			}
+		}
+		
+		if (begin <= length - 1) {
+			segmentString = expression.substring(begin, length);
+			onFindSegment(segmentString);
+		}
+	}
+	
+	public static String getVariantName(String value) {
+		if (value == null) {
+			return null;
+		}
+		
+		int begin = value.indexOf("@{") + 2;
+		int end = value.indexOf("}", begin);
+		
+		if (end <= begin) {
+			return null; 
+		}
+		
+		return value.substring(begin, end);
+	}
+	
+	public static String toSegmentString(String name) {
+		return "@{" + name + "}";
+	}
+	
+	protected boolean isKey(char value) {
+		return Flag_Variant == value;
+	}
+
+	protected void onFindSegment(String segment) throws Exception {
+		if (listener != null) {
+			listener.onSegment(segment);
+		}
+	}	
+	
+	protected void onFindVariant(char key, String variant) throws Exception {
+		if (listener != null) {
+			listener.addVariant(variant);
+		}		
+	}
+
+	private int getVariantLength(String expression, int pos, int max) throws Exception {
+		if (Flag_LeftQuote == expression.charAt(pos)) {
+			for (int i = pos + 1; i < max; i++) {
+				if (Flag_RightQuote == expression.charAt(i)) {
+					return i - pos - 1;
+				}
+			}
+		}
+		else {
+			throw new Exception("error parse param expression (" + pos + "):" + expression);
+		}
+		
+		throw new Exception("error parse param expression (" + pos + "):" + expression);
+	}
+	
+	public static void main(String[] args) {
+		System.out.println(getVariantName("123@{456}789"));
+	}
+
+}
diff --git a/src/frame/expression/VariantRequestParams.java b/src/frame/expression/VariantRequestParams.java
new file mode 100644
index 0000000..ccf9f3d
--- /dev/null
+++ b/src/frame/expression/VariantRequestParams.java
@@ -0,0 +1,22 @@
+package frame.expression;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class VariantRequestParams {
+	
+	private HttpServletRequest request;
+	
+	public VariantRequestParams() {
+		
+	}
+	
+	public VariantRequestParams(HttpServletRequest request) {
+		this.request = request;
+	}
+
+	public HttpServletRequest getRequest() {
+		return request;
+	}
+	
+
+}
diff --git a/src/frame/expression/VariantSegment.java b/src/frame/expression/VariantSegment.java
new file mode 100644
index 0000000..34cbc22
--- /dev/null
+++ b/src/frame/expression/VariantSegment.java
@@ -0,0 +1,52 @@
+package frame.expression;
+
+
+public class VariantSegment extends Segment {
+
+	protected String name;
+	protected String value;
+	
+	
+	public VariantSegment(String name) {
+		this.name = name;
+	}
+	
+	@Override
+	public Segment newInstance() {
+		VariantSegment result = new VariantSegment(name);
+		result.value = value;
+		
+		return result;
+	}
+	
+	@Override
+	public String getValueString() {
+		if (value == null) {
+			return VariantParser.toSegmentString(name);
+		}
+		
+		return value;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	@Override
+	public String toString() {
+		return "@{" + name + "}=" + value;
+	}
+
+	public void clearValue() {
+		value = null;
+	}
+	
+	public boolean isEmpty() {
+		return value == null;
+	}
+	
+}
diff --git a/src/frame/file/AppendMode.java b/src/frame/file/AppendMode.java
new file mode 100644
index 0000000..033bf78
--- /dev/null
+++ b/src/frame/file/AppendMode.java
@@ -0,0 +1,31 @@
+package frame.file;
+
+import frame.util.Util;
+
+public enum AppendMode {
+	Undefined, Append, ClearAndAppend, UpdateChanged, InsertChanged;
+	
+	 public AppendMode stringToAppendMode(String value) {
+         if (Util.isEmptyStr(value)) {
+             return AppendMode.Undefined;
+         }
+
+         value = value.toLowerCase();
+
+         if (AppendMode.Append.name().equalsIgnoreCase(value)) {
+             return AppendMode.Append;
+         }
+         else if (AppendMode.ClearAndAppend.name().equalsIgnoreCase(value)) {
+             return AppendMode.ClearAndAppend;
+         }
+         else if (AppendMode.UpdateChanged.name().equalsIgnoreCase(value)) {
+             return AppendMode.UpdateChanged;
+         }
+         else if (AppendMode.InsertChanged.name().equalsIgnoreCase(value)) {
+             return AppendMode.InsertChanged;
+         }
+
+         return AppendMode.Undefined;
+     }
+
+}
diff --git a/src/frame/file/CellDataType.java b/src/frame/file/CellDataType.java
new file mode 100644
index 0000000..c45774b
--- /dev/null
+++ b/src/frame/file/CellDataType.java
@@ -0,0 +1,5 @@
+package frame.file;
+
+public enum CellDataType {
+	 Boolean, Int, IntOrString, Decimal, DecimalOrString, Percent, DecimalORPercent, Date, DateTime, String, Error
+}
diff --git a/src/frame/file/CellTypes.java b/src/frame/file/CellTypes.java
new file mode 100644
index 0000000..42231b7
--- /dev/null
+++ b/src/frame/file/CellTypes.java
@@ -0,0 +1,71 @@
+package frame.file;
+
+import frame.data.DataType;
+import frame.util.Util;
+
+public class CellTypes {
+
+    public static CellDataType toExcelCellType(String type) {
+    	if (Util.isEmptyStr(type)) {
+            return null;
+        }
+
+        type = type.toLowerCase();
+
+        if ("boolean".equals(type)) {
+            return CellDataType.Boolean;
+        }
+        else if ("int".equals(type)) {
+            return CellDataType.Int;
+        }
+        else if ("decimal".equals(type)) {
+            return CellDataType.Decimal;
+        }
+        else if ("percent".equals(type)) {
+            return CellDataType.Percent;
+        }
+        else if ("date".equals(type)) {
+            return CellDataType.Date;
+        }
+        else if ("datetime".equals(type)) {
+            return CellDataType.DateTime;
+        }
+        else if ("string".equals(type)) {
+            return CellDataType.String;
+        }
+
+        return CellDataType.Error;
+
+    }
+    
+    public static CellDataType toExcelCellType(DataType type) {
+    	if (type == null || DataType.Void.equals(type)) {
+            return null;
+        }
+
+        if (DataType.Boolean.equals(type)) {
+            return CellDataType.Boolean;
+        }
+        else if (DataType.Int.equals(type)) {
+            return CellDataType.Int;
+        }
+        else if (DataType.Decimal.equals(type)) {
+            return CellDataType.Decimal;
+        }
+        else if (DataType.Decimal.equals(type)) {
+            return CellDataType.Percent;
+        }
+        else if (DataType.Date.equals(type)) {
+            return CellDataType.Date;
+        }
+        else if (DataType.Date.equals(type)) {
+            return CellDataType.DateTime;
+        }
+        else if (DataType.String.equals(type)) {
+            return CellDataType.String;
+        }
+
+        return CellDataType.Error;
+
+    }
+}
diff --git a/src/frame/file/DeleteMode.java b/src/frame/file/DeleteMode.java
new file mode 100644
index 0000000..47297d6
--- /dev/null
+++ b/src/frame/file/DeleteMode.java
@@ -0,0 +1,31 @@
+package frame.file;
+
+import frame.util.Util;
+
+public enum DeleteMode {
+	Undefined, HardDelete, SoftDelete;
+	
+	 public DeleteMode stringToDeleteMode(String value) {
+         if (Util.isEmptyStr(value)) {
+             return DeleteMode.Undefined;
+         }
+
+         value = value.toLowerCase();
+
+         if ("hard".equalsIgnoreCase(value)) {
+             return DeleteMode.HardDelete;
+         }
+         else if (DeleteMode.HardDelete.name().equalsIgnoreCase(value)) {
+             return DeleteMode.HardDelete;
+         }
+         else if (DeleteMode.SoftDelete.name().equalsIgnoreCase(value)) {
+             return DeleteMode.SoftDelete;
+         }
+         else if (DeleteMode.SoftDelete.name().equalsIgnoreCase(value)) {
+             return DeleteMode.SoftDelete;
+         }
+
+         return DeleteMode.Undefined;
+     }
+
+}
diff --git a/src/frame/file/Direction.java b/src/frame/file/Direction.java
new file mode 100644
index 0000000..108cb1d
--- /dev/null
+++ b/src/frame/file/Direction.java
@@ -0,0 +1,19 @@
+package frame.file;
+
+import frame.util.Util;
+
+public enum Direction {
+	Normal, Convert;
+	 public Direction stringToDirection(String value) {
+         if (Util.isEmptyStr(value)) {
+             return Direction.Normal;
+         }
+
+         if (Direction.Convert.name().equalsIgnoreCase(value)) {
+             return Direction.Convert;
+         }
+
+         return Direction.Normal;
+     }
+
+}
diff --git a/src/frame/file/FileIO.java b/src/frame/file/FileIO.java
new file mode 100644
index 0000000..d584a63
--- /dev/null
+++ b/src/frame/file/FileIO.java
@@ -0,0 +1,76 @@
+package frame.file;
+
+import java.util.ArrayList;
+import java.util.List;
+import frame.data.Entity;
+import frame.file.office.IOProcessor;
+import frame.util.MapList;
+
+public class FileIO extends IOProcessor {
+	private String code;
+    private MapList<FileIOItem> itemList;
+
+    public FileIO() {
+        itemList = new MapList<FileIOItem>();
+    }
+
+    public void load(Entity entity) {
+        code = entity.getString("code");
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public MapList<FileIOItem> getItems() {
+        return itemList;
+    }
+    
+    public List<FileIOItem> getItemList(String typecode) {
+        List<FileIOItem> result = new ArrayList<FileIOItem>();
+
+        List<FileIOItem> list = itemList.getItemList();
+
+        for (FileIOItem item : list) {
+            if (typecode.equals(item.getTypeCode())) {
+                result.add(item);
+            }
+        }
+
+        return result;
+    }
+
+
+    public void addItem(FileIOItem item) {
+        String id = item.getId();
+        itemList.add(id, item);
+    }
+
+    public FileIOItem getItem(String id) {
+        if (!itemList.contains(id)) {
+            return null;
+        }
+
+        return itemList.get(id);
+    }
+
+    public void clear() {
+        itemList.clear();
+    }
+
+    public void createRuntime() throws Exception {
+        List<FileIOItem> items = itemList.getItemList();
+        
+        for (FileIOItem ioItem : items) {
+            ioItem.createTableMeta();
+        }
+    }
+    
+	@Override
+	public IFileContext createContext(UploadResult result) {
+		FileIOContext ioContext = new FileIOContext(null);
+        ioContext.addParameters(result.getParameterProvider());
+		return ioContext;
+	}
+	
+}
diff --git a/src/frame/file/FileIOContainer.java b/src/frame/file/FileIOContainer.java
new file mode 100644
index 0000000..2069bb9
--- /dev/null
+++ b/src/frame/file/FileIOContainer.java
@@ -0,0 +1,230 @@
+package frame.file;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import frame.data.Entity;
+import frame.data.EntitySet;
+import frame.file.office.IOHandler;
+import frame.file.office.IOMapping;
+import frame.file.office.IOMappingItem;
+import frame.persist.NamedSQL;
+import frame.persist.SQLRunner;
+
+public class FileIOContainer {
+
+    private static FileIOContainer instance;
+    private static Object locker = new Object();
+
+    private Map<String, FileIO> fileIOMap;
+    private Map<String, FileIOItem> ioItemMap;
+    private Map<String, IOMapping> ioMappingMap;
+    private List<FileIO> fileIOList;
+    
+	 private FileIOContainer() {
+         fileIOMap = new HashMap<String, FileIO>();
+         ioItemMap = new HashMap<String, FileIOItem>();
+         ioMappingMap = new HashMap<String, IOMapping>();
+         fileIOList = new ArrayList<FileIO>();
+     }
+
+     public static FileIOContainer getInstance() {
+         if (instance == null) {
+             synchronized (locker) {
+            	 if (instance == null) {
+                     instance = new FileIOContainer();
+                 }
+			} 
+         }
+
+         return instance;
+     }
+     
+     public static FileIO get(String ioCode) {
+         getInstance();
+
+         if (ioCode == null) {
+             return null;
+         }
+
+         ioCode = ioCode.toLowerCase();
+
+         if (!instance.fileIOMap.containsKey(ioCode)) {
+             return null;
+         }
+
+         return instance.fileIOMap.get(ioCode);
+     }
+     
+     public static void load() throws Exception {
+         getInstance(); 
+         NamedSQL namedSQL;
+         Entity entity;
+         instance.clear();
+
+         //1. load mapping
+         namedSQL = NamedSQL.getInstance("getMappingList");
+         EntitySet mappingList = SQLRunner.getEntitySet(namedSQL);
+
+         while (mappingList.hasNext()) {
+             entity = mappingList.next();
+
+             IOMapping mapping = new IOMapping();
+             mapping.initLoad(entity);
+
+             instance.ioMappingMap.put(mapping.getId(), mapping);
+         }
+
+         //2. load mapping detail
+         namedSQL = NamedSQL.getInstance("getMappingDetails");
+         EntitySet mappingDetails = SQLRunner.getEntitySet(namedSQL);
+
+         while (mappingDetails.hasNext()) {
+             entity = mappingDetails.next();
+
+             IOMappingItem mappingItem = new IOMappingItem();
+             mappingItem.initLoad(entity);
+
+             IOMapping mapping = instance.getIOMapping(mappingItem.getParentId());
+
+             if (mapping == null) {
+                 return;
+             }
+
+             mapping.addItem(mappingItem);
+         }
+       
+         //3. load fileio
+         namedSQL = NamedSQL.getInstance("getFileIOList");
+         EntitySet fileIOList = SQLRunner.getEntitySet(namedSQL);
+
+         while (fileIOList.hasNext()) {
+             entity = fileIOList.next();
+             
+             FileIO fileIO = new FileIO();
+             fileIO.load(entity);
+
+             instance.addFileIO(fileIO);
+         }           
+
+         //4. load fileio item
+         namedSQL = NamedSQL.getInstance("getFileIOItemList");
+         EntitySet fileIOItemList = SQLRunner.getEntitySet(namedSQL);
+
+         while (fileIOItemList.hasNext()) {
+             entity = fileIOItemList.next();
+
+             String ioCode = entity.getString("code");
+             FileIO fileIO = instance.getFileIO(ioCode);
+
+             if (fileIO == null) {
+                 return;
+             }
+
+             FileIOItem ioItem = new FileIOItem();
+             ioItem.initLoad(entity);
+
+             IOMapping mapping = instance.ioMappingMap.get(ioItem.getMappingId());
+             ioItem.setMapping(mapping);
+
+             fileIO.addItem(ioItem);
+             instance.ioItemMap.put(ioItem.getId(), ioItem);
+         }
+
+         //5. create mapping runtime
+         for (FileIO fileIO : instance.fileIOList) {
+             fileIO.createRuntime();
+         }
+
+         //6. load ioItem handler
+         namedSQL = NamedSQL.getInstance("getIOItemHandlerList");
+         EntitySet privateHandlers = SQLRunner.getEntitySet(namedSQL);
+
+         while (privateHandlers.hasNext()) {
+             entity = privateHandlers.next();
+
+             IOHandler handler = new IOHandler();
+             handler.initLoad(entity);
+
+             FileIOItem ioItem = instance.getIOItem(handler.getItemId());
+
+             if (ioItem == null) {
+                 return;
+             }
+
+             ioItem.addHandler(handler);
+         }
+
+         //7. load fileIO handler
+         namedSQL = NamedSQL.getInstance("getFileIOHandlerList");
+         EntitySet publicHandlerList = SQLRunner.getEntitySet(namedSQL);
+
+         while (publicHandlerList.hasNext()) {
+             entity = publicHandlerList.next();
+
+             IOHandler handler = new IOHandler();
+             handler.initLoad(entity);
+
+             FileIO fileIO = instance.getFileIO(handler.getFileIoCode());
+
+             if (fileIO == null) {
+                 return;
+             }
+
+             fileIO.addHandler(handler);
+         }
+     }
+
+     private void clear() {
+         fileIOList.clear();
+
+         fileIOMap.clear();
+         ioItemMap.clear();
+         ioMappingMap.clear();
+     }
+
+     private FileIO getFileIO(String code) {
+         if (code == null) {
+             return null;
+         }
+
+         code = code.toLowerCase();
+
+         if (!instance.fileIOMap.containsKey(code)) {
+             return null;
+         }
+
+         return instance.fileIOMap.get(code);
+     }
+
+     private FileIOItem getIOItem(String id) {
+         if (!instance.ioItemMap.containsKey(id)) {
+             return null;
+         }
+
+         return instance.ioItemMap.get(id);
+     }
+
+     private IOMapping getIOMapping(String id) {
+         if (!instance.ioMappingMap.containsKey(id)) {
+             return null;
+         }
+
+         return instance.ioMappingMap.get(id);
+     }
+
+     private void addFileIO(FileIO fileIO) {
+         String ioCode = fileIO.getCode();
+
+         if (ioCode == null) {
+             return;
+         }
+
+         ioCode = ioCode.toLowerCase();
+         instance.fileIOMap.put(ioCode, fileIO);
+
+         fileIOList.add(fileIO);
+     }
+}
diff --git a/src/frame/file/FileIOContext.java b/src/frame/file/FileIOContext.java
new file mode 100644
index 0000000..8e6922b
--- /dev/null
+++ b/src/frame/file/FileIOContext.java
@@ -0,0 +1,229 @@
+package frame.file;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import frame.file.office.IOMappingItemRuntime;
+import frame.persist.NamedSQL;
+import frame.util.Util;
+
+public class FileIOContext implements IFileContext {
+	
+	private List<String> paramNames;
+	private Map<String, String> paramMap;
+	private FileIOItem ioItem;
+	
+	public FileIOContext(FileIOItem fileIoItem) {
+		paramMap = new HashMap<String, String>();
+		ioItem = fileIoItem;
+		initParamNames();
+	}
+	
+	public void setParametersTo(NamedSQL namedSQL) {
+        for (String name : paramNames) {
+            if (namedSQL.containsData(name)) {
+                String value = getParameter(name);
+
+                if (value == null) {
+                    continue;
+                }
+
+                namedSQL.setParam(name, value);
+            }
+        }
+    }
+	
+	public String getParameter(String name) {
+        if (Util.isEmptyStr(name)) {
+            return name;
+        }
+
+        name = name.toLowerCase();
+
+        if ("@totable".equalsIgnoreCase(name)) {
+            return ioItem.getToName();
+        }
+        else if ("@fromtable".equalsIgnoreCase(name)) {
+            return ioItem.getFromName();
+        }
+        else if ("@distinct".equalsIgnoreCase(name)) {
+            return ioItem.isDistinctSelect() ? "distinct" : "";
+        }
+        else if ("@updatefieldpairs".equalsIgnoreCase(name)) {
+            return getUpdateFieldPairs();
+        }
+        else if ("@updatefromfieldnames".equalsIgnoreCase(name)) {
+            return getUpdateFromFieldNames();
+        }
+        else if ("@inserttofieldnames".equalsIgnoreCase(name)) {
+             return getInsertToFieldNames();
+        }
+        else if ("@insertfromfieldnames".equalsIgnoreCase(name)) {
+            return getInsertFromFieldNames();
+        }
+        else if ("@filterfieldvalues".equalsIgnoreCase(name)) {
+            return getFilterFieldValues();
+        }
+        else if ("@keyfieldpairs".equalsIgnoreCase(name)) {
+            return getKeyFieldPairs();
+        }
+
+        if (paramMap.containsKey(name)) {
+            return paramMap.get(name);
+        }
+
+        return null;
+    }
+	
+    
+	private String getUpdateFieldPairs() {
+        StringBuilder result = new StringBuilder(", ");
+
+        List<IOMappingItemRuntime> runtimeList = ioItem.getUpdateMappingRuntime();
+        String toTable = ioItem.getToName();
+        String fromTable = ioItem.getFromName();
+
+        for (IOMappingItemRuntime itemRuntime : runtimeList) {
+            result.append(toTable + "." + itemRuntime.getToField() + " = " + fromTable + "." + itemRuntime.getFromField());
+        }
+
+	    return result.toString();
+    }
+
+	
+	public void addParameters(Map<String, String> paramsMap) {
+		if (paramsMap == null) {
+			return;
+		}
+		Set<String> keySet = paramsMap.keySet();
+		for (String key : keySet) {
+			key = key.toLowerCase();
+			if (!"@".equals(key.charAt(0))) {
+				key = "@" + key;
+			}
+			paramsMap.put(key, paramsMap.get(key));
+			paramNames.add(key);
+		}
+	}
+	
+	private String getUpdateFromFieldNames() {
+        return getMappingRuntimeList2String("update", true);
+    }
+	//TODO   INSERT  UPDATE ??
+    private String getInsertFromFieldNames() {
+    	return getMappingRuntimeList2String("insert", true);
+    }
+
+    private String getInsertToFieldNames() {
+        return getMappingRuntimeList2String("insert", false);
+    }
+    
+    private String getMappingRuntimeList2String (String type, boolean isfromField) {
+    	StringBuilder builder = new StringBuilder(", ");
+    	List<IOMappingItemRuntime> dataList = null;
+    	 
+    	if ("insert".equalsIgnoreCase(type)) {
+			dataList = ioItem.getInsertMappingRuntime();
+		}
+    	else if ("update".equalsIgnoreCase(type)) {
+			dataList = ioItem.getUpdateMappingRuntime();
+		}
+    	
+    	for (IOMappingItemRuntime ioMappingItemRuntime : dataList) {
+    		String field = null;
+    		if (isfromField) {
+    			field = ioMappingItemRuntime.getFromField();
+			}
+    		else {
+    			field = ioMappingItemRuntime.getToField();
+			}
+    		builder.append(field);
+		}
+    	
+    	return builder.toString();
+    }
+    
+    
+    private String getFilterFieldValues() {
+    	String andPair = getAndPair("filter");
+    	
+        return andPair;
+    }
+
+    private String getKeyFieldPairs() {
+    	String andPair = getAndPair("key");
+    	
+        return andPair;
+    }
+
+    private String getAndPair(String type) {
+    	String[] fields = null;
+    	if ("key".equalsIgnoreCase(type)) {
+    		fields = ioItem.getKeyFieldPairs();
+    		if (fields == null || fields.length == 0) {
+    			return ioItem.getFromName() + ".id = " + ioItem.getToName() + ".id";
+			}
+		}
+    	else if ("filter".equalsIgnoreCase(type)) {
+    		String[] filterFieldValues = ioItem.getFilterFieldValues();
+
+            if (filterFieldValues == null || filterFieldValues.length == 0) {
+                return "1=1";
+            }
+		}
+    	
+    	 // if define
+        StringBuilder result = new StringBuilder(" and ");
+
+        for (String fieldPair : fields) {
+            String keyFieldPair = setParametersTo(fieldPair);
+            result.append(keyFieldPair);
+        }
+
+        return result.toString();
+
+    }
+    
+    public String setParametersTo(String segment) {
+        if (segment == null) {
+            return segment;
+        }
+
+        segment = segment.toLowerCase();
+
+        for (String name : paramNames) {
+            if (segment.indexOf(name) >= 0) {
+                String value = getParameter(name);
+
+                if (value == null) {
+                    continue;
+                }
+
+                segment = segment.replace(name, value);
+            }
+        }
+
+        return segment;
+    }
+    
+	
+	private void initParamNames() {
+		paramNames = new ArrayList<String>();
+        paramNames.add("@taskid");
+        paramNames.add("@typecode");
+        paramNames.add("@totable");
+        paramNames.add("@fromtable");
+        paramNames.add("@distinct");
+        paramNames.add("@keyfieldpairs");
+        paramNames.add("@updatefieldpairs");
+        paramNames.add("@filterFieldValues");
+        paramNames.add("@fieldnames");
+        paramNames.add("@inserttofieldnames");
+        paramNames.add("@insertfromfieldnames");
+        paramNames.add("@updatefromfieldnames");
+		
+	}
+}
diff --git a/src/frame/file/FileIOItem.java b/src/frame/file/FileIOItem.java
new file mode 100644
index 0000000..0273372
--- /dev/null
+++ b/src/frame/file/FileIOItem.java
@@ -0,0 +1,220 @@
+package frame.file;
+
+import java.util.List;
+
+import frame.data.Entity;
+import frame.data.meta.EntityMeta;
+import frame.expression.VariantContext;
+import frame.file.office.IOMapping;
+import frame.file.office.IOMappingItemRuntime;
+import frame.file.office.IOMappingRuntime;
+import frame.file.office.IOProcessor;
+import frame.util.Util;
+
+public class FileIOItem extends IOProcessor implements IFileload{
+	
+	public static String TypeCode_Import = "import";
+	public static String TypeCode_DB = "db";
+	public static String TypeCode_Output = "output";
+
+	private String id;
+	private String fromName;
+	private String toName;
+	private String typeCode;
+	private String mappingId;
+	private boolean distinctSelect;
+	private boolean standardMove;
+	private String[] filterFieldValues;
+	private String[] keyFieldPairs;
+	private AppendMode appendMode;
+	private DeleteMode deleteMode;
+	private Direction direction;
+	private int fromRowNo;
+	private int toRowNo;
+	
+	private EntityMeta fromMeta;
+	private EntityMeta toMeta;
+	private IOMapping mapping;
+	private IOMappingRuntime mappingRuntime;
+	private IFileContext context;
+
+	public FileIOItem() {
+	    mapping = new IOMapping();
+	}
+	
+
+	@Override
+	public IFileContext createContext(UploadResult result) {
+		context = new FileIOContext(this);
+		context.addParameters(result.getParameterProvider());
+		return context;
+	}
+
+
+	@Override
+	public void initLoad(Entity entity) {
+		//TODO load
+	}
+    public static String extractSheetName(String value) {
+        if (Util.isEmptyStr(value)) {
+            return "Sheet1";
+        }
+
+        int begin = value.indexOf("[");
+
+        if (begin < 0) {
+            return "Sheet1";
+        }
+
+        int end = value.indexOf("]", begin);
+
+        if (end < 0) {
+            return "Sheet1";
+        }
+
+        return value.substring(begin + 1, end - begin - 1);
+    }
+
+    public static String extractFileName(String value) {
+        if (Util.isEmptyStr(value)) {
+            return null;
+        }
+
+        int end = value.indexOf("[");
+
+        if (end < 0) {
+            return value;
+        }
+
+        return value.substring(0, end - 1);
+    }
+    
+    public boolean existsFilterFieldValues() {
+        if (filterFieldValues == null) {
+            return false;
+        }
+
+        return filterFieldValues.length > 0;
+    }
+    
+	public void createTableMeta() throws Exception {
+        if (TypeCode_Import .equalsIgnoreCase(typeCode)) {
+            toMeta = EntityMeta.getInstance(toName);
+        }
+        else if (TypeCode_DB.equalsIgnoreCase(typeCode)) {
+            fromMeta = EntityMeta.getInstance(fromName);
+            toMeta = EntityMeta.getInstance(toName);
+        }
+        else if (TypeCode_Output.equalsIgnoreCase(typeCode)) {
+            fromMeta = EntityMeta.getInstance(fromName);
+        }
+    }
+
+	//getter
+	public String getId() {
+		return id;
+	}
+
+
+	public String getFromName() {
+		return fromName;
+	}
+
+
+	public String getToName() {
+		return toName;
+	}
+
+
+	public String getTypeCode() {
+		return typeCode;
+	}
+
+
+	public String getMappingId() {
+		return mappingId;
+	}
+
+
+	public boolean isDistinctSelect() {
+		return distinctSelect;
+	}
+
+
+	public boolean isStandardMove() {
+		return standardMove;
+	}
+
+
+	public String[] getFilterFieldValues() {
+		return filterFieldValues;
+	}
+
+
+	public String[] getKeyFieldPairs() {
+		return keyFieldPairs;
+	}
+
+
+	public AppendMode getAppendMode() {
+		return appendMode;
+	}
+
+
+	public DeleteMode getDeleteMode() {
+		return deleteMode;
+	}
+
+
+	public Direction getDirection() {
+		return direction;
+	}
+
+
+	public int getFromRowNo() {
+		return fromRowNo;
+	}
+
+
+	public int getToRowNo() {
+		return toRowNo;
+	}
+
+
+	public EntityMeta getFromMeta() {
+		return fromMeta;
+	}
+
+
+	public EntityMeta getToMeta() {
+		return toMeta;
+	}
+
+
+	public IOMapping getMapping() {
+		return mapping;
+	}
+	
+    public void setMapping(IOMapping mapping) {
+        this.mapping = mapping;
+    }
+
+    public List<IOMappingItemRuntime> getUpdateMappingRuntime() {
+        return mappingRuntime.getUpdateMappingRuntime();
+    }
+
+    public List<IOMappingItemRuntime> getInsertMappingRuntime() {
+        return mappingRuntime.getInsertMappingRuntime();
+    }
+	
+	public IOMappingRuntime getMappingRuntime() {
+		return mappingRuntime;
+	}
+
+
+	public IFileContext getContext() {
+		return context;
+	}
+	
+	
+}
diff --git a/src/frame/file/IFileContext.java b/src/frame/file/IFileContext.java
new file mode 100644
index 0000000..d0d24e4
--- /dev/null
+++ b/src/frame/file/IFileContext.java
@@ -0,0 +1,11 @@
+package frame.file;
+
+import java.util.Map;
+
+import frame.persist.NamedSQL;
+
+public interface IFileContext {
+	  void setParametersTo(NamedSQL namedSQL);
+	  
+	  void addParameters(Map<String, String> paramsMap);
+}
diff --git a/src/frame/file/IFileload.java b/src/frame/file/IFileload.java
new file mode 100644
index 0000000..aa05632
--- /dev/null
+++ b/src/frame/file/IFileload.java
@@ -0,0 +1,9 @@
+package frame.file;
+
+import frame.data.Entity;
+
+public interface IFileload {
+
+	public void initLoad(Entity entity);
+
+}
diff --git a/src/frame/file/UploadResult.java b/src/frame/file/UploadResult.java
new file mode 100644
index 0000000..4848131
--- /dev/null
+++ b/src/frame/file/UploadResult.java
@@ -0,0 +1,151 @@
+package frame.file;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import frame.persist.NamedSQL;
+import frame.persist.SQLRunner;
+import frame.util.Util;
+
+public class UploadResult {
+	
+	private Map<String, String> parameterProvider;
+	private String id;
+    private Boolean success;
+    private Boolean showDetail;
+    private List<String> messages;
+    private List<String> details;
+    private int errorCount;
+    private int successCount;
+    private Date begintime;
+    private Date endtime;
+
+    private String typeCode;
+    public NamedSQL workingSQL;
+
+    public UploadResult(HttpServletRequest request) {
+    	messages = new ArrayList<String>();
+        details = new ArrayList<String>();
+
+        id = Util.newShortGUID();
+        success = true;
+        showDetail = false;
+
+        parameterProvider = new HashMap<String, String>();
+        parameterProvider.put("taskid", id);
+                      
+        Set<String> nameSet = request.getParameterMap().keySet();
+        for (String name : nameSet) {
+        	parameterProvider.put("@" + name, request.getParameter(name));
+		}
+    }
+    
+    public void succeed() {
+        success = true;
+        errorCount = 0;
+        successCount = 0;
+        begintime = new Date();
+    }
+    
+    public void fail(String code, String message) {
+        success = false;
+        showDetail = true;
+        messages.add(message);
+    }
+    
+    public void fail(String code, String message, int count) {
+        success = false;
+        messages.add(message);
+        errorCount = count;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public int getErrorCount() {
+        return errorCount;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void writeBegin() throws Exception {
+        String sql = "insert into BLUE_TT_UploadRecord (id, begintime) values ('" + id + "', GETDATE())";
+        SQLRunner.execSQL(sql);
+    }
+
+    public void writeEnd() throws Exception {
+        String errorMessage = null;
+        if (messages.size() > 0) {
+            errorMessage = messages.get(0);
+        }
+
+        if (errorMessage != null) {
+            if (errorMessage.length() > 254) {
+                errorMessage = errorMessage.substring(0, 230);
+            }
+            errorMessage = errorMessage.replace("'", "\"");
+        }
+
+        String sql = "update BLUE_TT_UploadRecord set "
+                    + "errormessage=" + Util.quotedStr(errorMessage) + ","
+                    + "errorCount=" + errorCount + ","
+                    + "endtime=GETDATE()"
+                    + " where id=" + Util.quotedStr(id);
+        SQLRunner.execSQL(sql);
+
+        endtime = new Date();
+    }
+
+    public int getSuccessCount() {
+        return successCount;
+    }
+
+    public List<String> getMessages() {
+        return messages;
+    }
+
+    public void setSuccessCount(int cnt) {
+        successCount = cnt;
+    }
+
+    public String getTypeCode() {
+        return typeCode;
+    }
+
+    public void setTypeCode(String value) {
+        typeCode = value;
+    }
+
+    public Date getBeginTime() {
+        return begintime;
+    }
+
+    public Date getEndTime() {
+        return endtime;
+    }
+
+    public void setWorkingSQL(NamedSQL namedSql) {
+        workingSQL = namedSql;
+    }
+
+    public void addMessage(String message) {
+        messages.add(message);
+    }
+    
+    public void addDetail(String detail) {
+        details.add(detail);
+    }
+
+    public Map<String, String> getParameterProvider() {
+        return parameterProvider;
+    }
+}
diff --git a/src/frame/file/exception/DataInvalidException.java b/src/frame/file/exception/DataInvalidException.java
new file mode 100644
index 0000000..f13a1d7
--- /dev/null
+++ b/src/frame/file/exception/DataInvalidException.java
@@ -0,0 +1,5 @@
+package frame.file.exception;
+
+public class DataInvalidException extends Exception {
+
+}
diff --git a/src/frame/file/exception/FileInvalidException.java b/src/frame/file/exception/FileInvalidException.java
new file mode 100644
index 0000000..95343a0
--- /dev/null
+++ b/src/frame/file/exception/FileInvalidException.java
@@ -0,0 +1,5 @@
+package frame.file.exception;
+
+public class FileInvalidException extends Exception {
+	
+}
diff --git a/src/frame/file/office/Engine.java b/src/frame/file/office/Engine.java
new file mode 100644
index 0000000..b2268f8
--- /dev/null
+++ b/src/frame/file/office/Engine.java
@@ -0,0 +1,125 @@
+package frame.file.office;
+
+import java.io.Console;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.codec.net.URLCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.corba.se.impl.protocol.JIDLLocalCRDImpl;
+
+import frame.data.DataContext;
+import frame.file.FileIOContainer;
+import frame.file.UploadResult;
+import frame.file.processor.Monitor;
+import frame.util.Util;
+
+public class Engine {
+	
+	private static Engine instance;
+    private static Object locker = new Object();
+    private Logger logger;
+    private ExcelLoader excelLoader;
+
+    private Engine() {
+    	logger = LoggerFactory.getLogger(this.getClass());
+        excelLoader = new ExcelLoader(logger);
+        
+    }
+
+    public static Engine getInstance() {
+        synchronized (locker) {
+            if (instance == null) {
+                instance = new Engine();
+            }
+
+            return instance;
+        }
+    }
+    
+    public static void download(HttpServletResponse response, String iocode, DataContext dataContext, Map<String, String> parameterProvider) {
+        getInstance();
+
+        StringBuilder log = new StringBuilder();
+
+        try {
+        	new JIDLLocalCRDImpl(orb, scid, ior)
+            FileIOContainer.load();
+            ExcelWriter excelWriter = new ExcelWriter(Monitor.getDownloadProgressor(), parameterProvider);
+            DownloadResult result = excelWriter.writeOneFile(iocode, dataContext);
+
+            String filename = result.getFilename();
+            response.addHeader("Content-Type", "application/octet-stream");
+            filename = URLEncoder.encode(filename, "utf-8");
+            response.addHeader("Content-Disposition", "attachment;filename=" + filename);
+            response.TransmitFile(result.getPath());
+        }
+        catch (Exception e) {
+            JsonBuilder json = new JsonBuilder();
+            json.beginObject();
+            json.addValue("log", log.toString());
+            json.addValue("error", e.getMessage());
+
+            json.beginArray("detail");
+            List<String> details = Monitor.getDownloadProgressor().getMessageList();
+            
+            for (int i = 0; i < details.size(); i++) {
+                json.addValue(details.get(i));
+            }
+            
+            json.endArray();
+            json.endObject();
+
+            response.Write(json.ToString());
+        }
+    }
+
+    public static UploadResult upload(String iocode, FileInfo file, HttpServletRequest request) {
+        UploadResult result = new UploadResult(request);
+       
+        result.writeBegin();
+        try {
+            getInstance();
+            FileIOContainer.load();
+            instance.excelLoader.loadOneFile(result, iocode, file);
+        }
+        catch (Exception e){
+            result.fail("error", e.getMessage());
+        }
+        finally {
+            result.writeEnd();
+        }
+
+        return result;
+    }
+
+    public static UploadResult testDataProcess(String iocode, HttpServletRequest request) {
+        UploadResult result = new UploadResult(request);
+
+        result.writeBegin();
+        try {
+            getInstance();
+            instance.excelLoader.testDataProcess(result, iocode);
+        }
+        catch (Exception e){
+            result.fail("error", e.getMessage());
+        }
+        finally {
+            result.writeEnd();
+        }
+
+        return result;
+    }
+
+    private void showHelloMessage() {
+        logger.info("Excel瀵煎叆鏈嶅姟鍣�  V1.0宸插惎鍔�");
+    }
+
+
+}
diff --git a/src/frame/file/office/ExcelHandler.java b/src/frame/file/office/ExcelHandler.java
new file mode 100644
index 0000000..265c836
--- /dev/null
+++ b/src/frame/file/office/ExcelHandler.java
@@ -0,0 +1,474 @@
+package frame.file.office;
+
+import java.util.Map;
+
+
+import org.apache.poi.ss.format.CellFormat;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.dom4j.rule.Stylesheet;
+
+import frame.data.EntitySet;
+import frame.file.FileIOContext;
+import frame.file.FileIOItem;
+import frame.file.processor.Processor;
+
+public class ExcelHandler {
+	private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
+    protected Processor progressor;
+    protected Map<String, String> parameterProvider;
+    protected OpenXmlWriter writer;
+    protected OpenXmlReader reader;
+    protected ColumnReader columnReader;
+
+    protected SpreadsheetDocument sheetDocument;
+    protected WorkbookPart workbookPart;
+    protected Stylesheet styleSheet;
+    protected SharedStringsTable sharedStringTable;
+    protected CellFormat cellFormat;
+    protected Sheets sheets;
+
+    protected FileIOItem workingIoItem;
+    protected FileIOContext workingIoContext;
+    protected int[] index;
+    protected IExcelValueTranslator[] translator;
+    protected int rowIndex = 1;
+
+    protected int percentStyleId;
+    protected int dateStyleId;
+    protected int dateTimeStyleId;
+    protected int numberFormatId;
+
+
+    public ExcelHandler(Processor progressor, Map<String, String> parameterProvider) {
+        columnReader = new ColumnReader();
+        numberFormatId = 254;
+
+        this.progressor = progressor;
+        this.parameterProvider = parameterProvider;
+    }
+
+    public void processFile(String file) {
+        sheetDocument = SpreadsheetDocument.Open(file, true);
+        try {
+            workbookPart = sheetDocument.WorkbookPart;
+            try {
+                //1. style
+                styleSheet = workbookPart.WorkbookStylesPart.Stylesheet;
+                if (styleSheet == null) {
+                    styleSheet = new Stylesheet();
+                }
+
+                createCellStyle();
+
+                //2. shared string
+                sharedStringTable = workbookPart.SharedStringTablePart.SharedStringTable;
+                if (sharedStringTable == null) {
+                    sharedStringTable = new SharedStringsTable();
+                }
+
+                //3. sheets 
+                sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
+                processSheets();
+            }
+            finally {
+                workbookPart.Workbook.Save();
+            }
+        }
+        finally {
+            sheetDocument.Close();
+        }
+    }
+
+    protected void processSheets() {
+
+    }
+
+    protected void writeOneSheet(Sheet sheet, EntitySet entitySet) {
+        rowIndex = workingIoItem.getToRowNo();
+
+        WorksheetPart sourceSheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.);
+        String sourceSheetPartId = workbookPart.GetIdOfPart(sourceSheetPart);
+
+        WorksheetPart destSheetPart = workbookPart.AddNewPart<WorksheetPart>();
+
+        reader = OpenXmlReader.Create(sourceSheetPart);
+        try {
+            writer = OpenXmlWriter.Create(destSheetPart);
+            try {
+                bool skip = false;
+
+                while (reader.Read()) {
+                    Type elementType = reader.ElementType;
+
+                    if (elementType == typeof(Row)) {
+                        if (reader.IsStartElement) {
+                            skip = true;
+                        }
+                        else if (reader.IsEndElement) {
+                            skip = false;
+                        }
+
+                        continue;
+                    }
+
+                    if (skip) {
+                        continue;
+                    }
+
+                    if (elementType == typeof(SheetData)) {
+                        if (reader.IsEndElement) {
+                            continue;
+                        }
+
+                        doWriteOneSheet(sourceSheetPart, entitySet);
+                    }
+                    else {
+                        if (reader.IsStartElement) {
+                            writer.WriteStartElement(reader);
+                        }
+                        else if (reader.IsEndElement) {
+                            writer.WriteEndElement();
+                        }
+                    }
+                }
+            }
+            finally {
+                writer.Close();
+                writer = null;
+            }
+        }
+        finally {
+            reader.Close();
+            reader = null;
+        }
+
+        workbookPart.DeletePart(sourceSheetPart);
+        workbookPart.ChangeIdOfPart(destSheetPart, sourceSheetPartId);
+    }
+
+    protected void doWriteOneSheet(WorksheetPart worksheetPart, EntitySet entitySet) {
+        writer.WriteStartElement(new SheetData());
+        try {
+            //1. header
+            progressor.newPhase("HandleHeader", "澶勭悊鏍囬");
+            writeHeader(worksheetPart);
+            progressor.endPhase();
+
+            //2. mapping
+            progressor.newPhase("CreateMapping", "鍒涘缓Mapping");
+            createColumnMappings();
+            progressor.endPhase();
+
+            //3.
+            progressor.newPhase("WriteRows", "鍐欏叆鏁版嵁");
+            writeRows(entitySet);
+            progressor.endPhase();
+        }
+        finally {
+            writer.WriteEndElement();
+        }
+    }
+
+    protected void writeHeader(WorksheetPart worksheetPart) {
+        IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();
+
+        int pos = 1;
+        foreach (Row row in rows ) {
+            columnReader.read(row, sharedStringTable, cellFormats);
+            writer.WriteElement(row);
+
+            pos++;
+            if (pos >= rowIndex) {
+                break;
+            }
+        }
+    }
+
+    protected void createColumnMappings() {
+        //1. create mapping run time
+        List<string> excelColumns = columnReader.getColumnNames();
+        workingIoItem.createMappingRuntime(excelColumns, workingIoContext);
+
+        //2. init index and translator
+        index = new int[excelColumns.Count];
+        translator = new IExcelValueTranslator[excelColumns.Count];
+
+        IOMappingItemRuntimeList itemRuntimeList = workingIoItem.getInsertMappingRuntime();
+
+        int i = 0;
+        foreach (String column in excelColumns) {
+            if (!itemRuntimeList.contaisToField(column)) {
+                index[i++] = -1;
+                continue;
+            }
+
+            IOMappingItemRuntime itemRuntime = itemRuntimeList.getItemByToField(column);
+            index[i] = itemRuntime.getFromIndex();
+            translator[i] = Translator.createExcelValueTranslator(itemRuntime.getExportType());
+
+            i++;
+        }
+    }
+
+    public void writeRows(EntitySet entitySet) {
+        while (entitySet.hasNext()) {
+            Entity entity = entitySet.getCurrent();
+            WriteOneRow(entity);
+        }
+
+        progressor.appendMesage("鍏卞啓鍏ユ暟鎹�" + entitySet.size() + "琛�");
+    }
+
+    public void WriteOneRow(Entity entity) {
+        Row row = new Row();
+        row.RowIndex = new UInt32Value(rowIndex);
+
+        writer.WriteStartElement(row);
+        try {
+            int columnIndex = 0; int max = index.Length;
+
+            for (int i = 0; i < max; i++) {
+                int idx = index[i];
+
+                if (idx < 0) {
+                    continue;
+                }
+
+                Object value = entity.getObjectByIndex(idx);
+                writeOneCell(i, translator[i], value);
+                
+                columnIndex++;
+            }
+        }
+        finally {
+            writer.WriteEndElement();
+        }
+
+        rowIndex++;
+    }
+
+    public void writeOneCell(int columnIndex, IExcelValueTranslator translator, Object data) {
+        Cell cell = new Cell();
+        cell.CellReference = toCellReference(columnIndex) + rowIndex;
+
+        if (data == null || data == DBNull.Value) {
+            writer.WriteElement(cell);
+            return;
+        }
+
+        CellDataType type = CellDataType.Error;
+        String value = translator.toString(ref type, data);
+
+        if (CellDataType.Boolean == type) {
+            WriteBoolean(cell, value);
+        }
+        else if (CellDataType.Int == type) {
+            WriteNumber(cell, value);
+        }
+        else if (CellDataType.Decimal == type) {
+            WriteNumber(cell, value);
+        }
+        else if (CellDataType.Percent == type) {
+            WritePercent(cell, value);
+        }
+        else if (CellDataType.String == type) {
+            WriteString(cell, value);
+        }
+        else if (CellDataType.Date == type) {
+            WriteDate(cell, value);
+        }
+        else if (CellDataType.DateTime == type) {
+            WriteDateTime(cell, value);
+        }
+
+        writer.WriteElement(cell);
+    }
+
+    protected void WriteBoolean(Cell cell, string value) {
+        cell.CellValue = new CellValue(value);
+        cell.DataType = new EnumValue<CellValues>(CellValues.Boolean);
+    }
+
+    protected void WriteNumber(Cell cell, string value) {
+        cell.CellValue = new CellValue(value);
+        cell.DataType = new EnumValue<CellValues>(CellValues.Number);
+    }
+
+    protected void WritePercent(Cell cell, string value) {
+        cell.CellValue = new CellValue(value);
+        cell.DataType = new EnumValue<CellValues>(CellValues.Number);
+        cell.StyleIndex = percentStyleId;
+    }
+    protected void WriteDate(Cell cell, string value) {
+        cell.CellValue = new CellValue(value);
+        cell.StyleIndex = dateStyleId;
+    }
+
+    protected void WriteDateTime(Cell cell, string value) {
+        cell.CellValue = new CellValue(value);
+        cell.StyleIndex = dateStyleId;
+    }
+
+    protected void WriteString(Cell cell, string value) {
+        cell.CellValue = new CellValue(value);
+        cell.DataType = new EnumValue<CellValues>(CellValues.String);
+    }
+
+    protected void WriteSharedString(Cell cell, string value) {
+        int stringId = InsertSharedStringItem(value);
+        cell.CellValue = new CellValue(stringId.ToString());
+        cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
+    }
+
+    protected void WriteInlineString(Cell cell, string value) {
+        InlineString inlineString = new InlineString();
+        Text cellValueText = new Text { Text = value };
+        inlineString.AppendChild(cellValueText);
+        cell.Append(inlineString);
+        cell.DataType = new EnumValue<CellValues>(CellValues.InlineString);
+    }
+
+    protected int InsertSharedStringItem(string text) {
+        int i = 0;
+        // Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
+        foreach (SharedStringItem item in sharedStringTable.Elements<SharedStringItem>()) {
+            if (item.InnerText == text) {
+                return i;
+            }
+
+            i++;
+        }
+
+        // The text does not exist in the part. Create the SharedStringItem and return its index.
+        sharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));
+        sharedStringTable.Save();
+        return i;
+    }
+
+    protected string toCellReference(int columnIndex) {
+        // start form 0;
+        string result = "";
+
+        int num = columnIndex;
+        do {
+            int i = num % 26;
+            result = alphabet[i] + result;
+            num = num / 26 - 1;
+        } 
+        while (num > -1);
+
+        if (string.IsNullOrEmpty(result)) {
+            result = "A";
+        }
+
+        return result;
+    }
+
+    protected Sheet getSheetByName(String sheetname) {
+        IEnumerable<Sheet> sheetList = sheets.Elements<Sheet>();
+        Sheet sheet = null;
+
+        //1. sheet name is null
+        if (string.IsNullOrEmpty(sheetname)) {
+            sheet = sheetList.First<Sheet>();
+        }
+
+        if (sheet != null) {
+            return sheet;
+        }
+
+        sheetname = sheetname.ToLower();
+
+        //2. locate by name
+        sheet = sheetList.FirstOrDefault<Sheet>(s => s.Name.Value.ToLower().Equals(sheetname));
+
+        if (sheet != null) {
+            return sheet;
+        }
+
+        //3. 
+        sheet = sheetList.First<Sheet>();
+
+        if (sheet != null) {
+            return sheet;
+        }
+
+        return null;
+    }
+
+    protected void createCellStyle() {
+        //1. create style
+        percentStyleId = createPercentStyleFormat();
+        dateStyleId = createDateStyleFormat();
+        dateTimeStyleId = createDateTimeStyleFormat();
+
+        //2. save
+        styleSheet.Save();
+    }
+
+    protected UInt32Value createPercentStyleFormat() {
+        CellFormat cellFormat = new CellFormat();
+        cellFormat.NumberFormatId = 10;
+        cellFormat.ApplyNumberFormat = true;
+
+        styleSheet.CellFormats.Append(cellFormat);
+
+        UInt32Value result = styleSheet.CellFormats.Count;
+        styleSheet.CellFormats.Count++;
+        return result;
+    }
+
+    protected UInt32Value createDateStyleFormat() {
+        //1. add number fromat
+        NumberingFormats numberingFormats = styleSheet.NumberingFormats;
+        if (numberingFormats == null) {
+            numberingFormats = new NumberingFormats();
+        }
+
+        NumberingFormat numberingFormat = new NumberingFormat();
+        numberingFormat.NumberFormatId = numberFormatId++;
+        numberingFormat.FormatCode = "yyyy\\-mm\\-dd";
+
+        numberingFormats.Append(numberingFormat);
+
+        //2. add cell fromat
+        CellFormat cellFormat = new CellFormat();
+        cellFormat.NumberFormatId = numberingFormat.NumberFormatId;
+        cellFormat.ApplyNumberFormat = true;
+
+        styleSheet.CellFormats.Append(cellFormat);
+
+        UInt32Value result = styleSheet.CellFormats.Count;
+        styleSheet.CellFormats.Count++;
+        return result;
+    }
+
+    protected UInt32Value createDateTimeStyleFormat() {
+        //1. add number fromat
+        NumberingFormats numberingFormats = styleSheet.NumberingFormats;
+        if (numberingFormats == null) {
+            numberingFormats = new NumberingFormats();
+        }
+
+        NumberingFormat numberingFormat = new NumberingFormat();
+        numberingFormat.NumberFormatId = numberFormatId++;
+        numberingFormat.FormatCode = "yyyy\\-mm\\-dd hh:mm:ss";
+
+        numberingFormats.Append(numberingFormat);
+
+        //2. add cell fromat
+        CellFormat cellFormat = new CellFormat();
+        cellFormat.NumberFormatId = numberingFormat.NumberFormatId;
+        cellFormat.ApplyNumberFormat = true;
+
+        styleSheet.CellFormats.Append(cellFormat);
+
+        UInt32Value result = styleSheet.CellFormats.Count;
+        styleSheet.CellFormats.Count++;
+        return result;
+    }
+}
+
+}
diff --git a/src/frame/file/office/IOHandler.java b/src/frame/file/office/IOHandler.java
new file mode 100644
index 0000000..62327cf
--- /dev/null
+++ b/src/frame/file/office/IOHandler.java
@@ -0,0 +1,110 @@
+package frame.file.office;
+
+import frame.data.Entity;
+import frame.expression.VariantContext;
+import frame.file.IFileContext;
+import frame.file.IFileload;
+import frame.file.UploadResult;
+import frame.persist.NamedSQL;
+import frame.persist.SQLRunner;
+import frame.util.Util;
+
+public class IOHandler implements IFileload{
+	  private String id;
+	  private String fileIoCode;
+	  private String itemId;
+      private String sqlName;
+      private int no;
+      private String eventCode;
+      private String resultCode;
+
+      public IOHandler() {
+
+      }
+      
+    @Override
+	public void initLoad(Entity entity) {
+          id = entity.getString("id");
+          fileIoCode = entity.getString("fileiocode");
+          itemId = entity.getString("itemid");
+          sqlName = entity.getString("sqlname");
+          sqlName = entity.getString("sqlname");
+          eventCode = entity.getString("eventcode");
+          resultCode = entity.getString("resultcode");
+          String noString = entity.getString("no");
+          
+          if (Util.isEmptyStr(noString)) {
+			no = Integer.parseInt(noString);
+          }
+          
+          if (eventCode != null) {
+              eventCode = eventCode.toLowerCase();
+          }
+
+          if (resultCode != null) {
+              resultCode = resultCode.toLowerCase();
+          }
+      }
+
+      public void exec(UploadResult result, IFileContext context) throws Exception {
+          NamedSQL namedSql = NamedSQL.getInstance(sqlName);
+          result.setWorkingSQL(namedSql);
+
+          context.setParametersTo(namedSql);
+
+          if ("errorcount".equalsIgnoreCase(resultCode)) {
+              int cnt = SQLRunner.execSQL(namedSql.getSQLString());
+
+              if (cnt > 0) {
+                  result.fail("error_InvalidData", "瀛樺湪涓嶅悎娉曟暟鎹紙" + cnt + ")", cnt);
+              }
+          }
+          else if ("successcount".equalsIgnoreCase(resultCode)) {
+              int cnt = SQLRunner.execSQL(namedSql.getSQLString());
+              result.setSuccessCount(cnt);
+          }
+          else {
+              SQLRunner.execSQL(namedSql.getSQLString());
+          }
+      }
+
+    
+	public boolean equalEvent(String code) {
+		if (Util.isEmptyStr(code)) {
+	          return false;
+	      }
+	      
+		return eventCode.equalsIgnoreCase(code);
+	}
+
+	public String getId() {
+		return id;
+  	}
+
+  	public String getFileIoCode() {
+  		return fileIoCode;
+  	}
+
+  	public String getItemId() {
+  		return itemId;
+  	}
+
+  	public String getSqlName() {
+  		return sqlName;
+  	}
+
+  	public int getNo() {
+  		return no;
+  	}
+
+  	public String getEventCode() {
+  		return eventCode;
+  	}
+
+  	public String getResultCode() {
+  		return resultCode;
+  	}
+
+	
+
+  }
diff --git a/src/frame/file/office/IOMapping.java b/src/frame/file/office/IOMapping.java
new file mode 100644
index 0000000..7e9a695
--- /dev/null
+++ b/src/frame/file/office/IOMapping.java
@@ -0,0 +1,226 @@
+package frame.file.office;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.org.apache.regexp.internal.recompile;
+
+import frame.data.Entity;
+import frame.data.meta.EntityMeta;
+import frame.data.meta.Field;
+import frame.file.Direction;
+import frame.file.FileIOContext;
+import frame.file.FileIOItem;
+import frame.file.IFileload;
+import frame.util.Util;
+
+public class IOMapping implements IFileload{
+
+	private String id;
+	private String name;
+	private boolean open;
+	private int typeCode;
+	private List<IOMappingItem> itemList;
+	private Map<String, IOMappingItem> fromItemMap;
+	private Map<String, IOMappingItem> toItemMap;
+
+	public IOMapping() {
+		itemList = new ArrayList<IOMappingItem>();
+		fromItemMap = new HashMap<String, IOMappingItem>();
+		toItemMap = new HashMap<String, IOMappingItem>();
+	}
+
+	@Override
+	public void initLoad(Entity entity) {
+		// TODO Auto-generated method stub
+		
+	}
+	public IOMappingRuntime createRuntime(FileIOContext context, String condition, EntityMeta fromMeta, EntityMeta toMeta, Direction direction) throws Exception {
+		List<IOMappingItemRuntime> updateMappingRuntime = new ArrayList<IOMappingItemRuntime>();
+        List<IOMappingItemRuntime> insertMappingRuntime = new ArrayList<IOMappingItemRuntime>();
+        
+        for (IOMappingItem mappingItem : itemList) {
+        	String fromField, toField;
+        	if (Direction.Normal == direction) {
+				fromField = mappingItem.getFromField();
+				toField = mappingItem.getToField();
+			}
+        	else {
+				fromField = mappingItem.getToField();
+				toField = mappingItem.getFromField();
+			}
+        	
+        	if (context != null) {
+				fromField = context.setParametersTo(fromField);
+				toField = context.setParametersTo(toField);
+			}
+        	
+        	Field fieldByFrom = fromMeta.get(fromField);
+        	Field fieldByto = fromMeta.get(toField);
+        	
+        	if (fieldByFrom == null || fieldByto == null) {
+        		if (FileIOItem.TypeCode_DB.equalsIgnoreCase(condition)) {
+					if (mappingItem.isInsertIgnore() || mappingItem.isUpdateIgnore()) {
+						continue;
+					}
+					else {
+						throw new Exception("IO Mapping fields not in table:" + mappingItem.toString() + " " + fromMeta.getName() + ", " + toMeta.getName());
+					}
+				}
+        		else {
+					continue;
+				}
+			}
+        	
+        	IOMappingItemRuntime mappingItemRuntime = new IOMappingItemRuntime(mappingItem, fromField, fieldByFrom, toField, fieldByto);
+        	
+        	if (!mappingItem.isInsertIgnore()) {
+        		insertMappingRuntime.add(mappingItemRuntime);
+			}
+        	
+        	if (!mappingItem.isUpdateIgnore()) {
+        		updateMappingRuntime.add(mappingItemRuntime);
+			}
+        
+		}
+        
+        if (open) {
+	        List<Field> fields = fromMeta.getFields();
+	        for (Field field : fields) {
+	        	String fieldName = field.getName();
+				if (!toMeta.contains(fieldName)) {
+					continue;
+				}
+				
+				Field fromField = fromMeta.get(fieldName);
+				Field toField = toMeta.get(fieldName);
+				
+				IOMappingItemRuntime itemRuntime = new IOMappingItemRuntime(null, fieldName, fromField, fieldName, toField);
+				
+				if (!fromItemMap.containsKey(field)) {
+                    updateMappingRuntime.add(itemRuntime);
+                }
+
+                if (!fromItemMap.containsKey(field)) {
+                    insertMappingRuntime.add(itemRuntime);
+                } 
+			}
+        }
+        
+        IOMappingRuntime ioMappingRuntime = new IOMappingRuntime(insertMappingRuntime, updateMappingRuntime);
+        
+        return ioMappingRuntime;
+	}
+	
+	public int size() {
+        return itemList.size();
+    }
+
+    public List<IOMappingItem> getList() {
+        return itemList;
+    }
+
+    public void addItem(IOMappingItem item) {
+        String fromField = item.getFromField();
+        String toField = item.getToField();
+
+        itemList.add(item);
+
+        if (fromField != null) {
+            fromItemMap.put(fromField, item);
+        }
+
+        if (toField != null) {
+        	toItemMap.put(toField, item);
+        }
+    }
+    
+    public String getFromField(String toField) {
+    	return convertField(toField, true);
+    }
+    
+    public String getToField(String fromField) {
+       return convertField(fromField, false);
+    }
+    
+    private String convertField(String field, boolean isFromField) {
+    	IOMappingItem item = getIoMappingItem(field, isFromField);
+    	
+    	if (isFromField) {
+    		return item.getToField();
+		}
+    	else {
+    		return item.getFromField();
+		}
+    	
+    }
+    
+    public void clear() {
+    	if (itemList != null) {
+    		itemList.clear();
+		}
+    	
+    	if (fromItemMap != null) {
+    		fromItemMap.clear();
+		}
+    
+    	if (toItemMap != null) {
+    		toItemMap.clear();
+		}
+    }
+
+    public IOMappingItem getItemByFromField(String fromField) {
+    	return getIoMappingItem(fromField, true);
+    }
+	
+    public IOMappingItem getItemByToField(String toField) {
+    	return getIoMappingItem(toField, false);
+    }
+    
+    private IOMappingItem getIoMappingItem(String field, boolean isFromField) {
+		Map<String, IOMappingItem> itemMap = null;
+    	if (Util.isEmptyStr(field)) {
+    		return null;
+    	}
+    	 
+    	field = field.toLowerCase();
+    	
+    	if (isFromField) {
+    		itemMap = fromItemMap;
+		}
+    	else {
+    		itemMap = toItemMap;
+		}
+    	
+    	if (!itemMap.containsKey(field)) {
+    		return null;
+    	}
+
+    	IOMappingItem item = itemMap.get(field);
+		return item;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public boolean isOpen() {
+		return open;
+	}
+
+	public int getTypeCode() {
+		return typeCode;
+	}
+
+	public List<IOMappingItem> getItemList() {
+		return itemList;
+	}
+
+
+}
diff --git a/src/frame/file/office/IOMappingItem.java b/src/frame/file/office/IOMappingItem.java
new file mode 100644
index 0000000..c360401
--- /dev/null
+++ b/src/frame/file/office/IOMappingItem.java
@@ -0,0 +1,76 @@
+package frame.file.office;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.ss.format.CellFormatType;
+
+import frame.data.Entity;
+import frame.file.CellDataType;
+import frame.file.CellTypes;
+import frame.file.IFileload;
+import frame.util.Util;
+
+public class IOMappingItem implements IFileload{
+	private String id;
+	private String parentId;
+	private String fromField;
+	private String toField;
+	private boolean updateIgnore;
+	private boolean insertIgnore;
+	private CellDataType[] exportType;
+	
+	@Override
+	public void initLoad(Entity entity) {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	private CellDataType[] parseExportType(String exportType) {
+		//TODO   parseExportType
+		if (Util.isEmptyStr(exportType)) {
+            return null;
+        }
+
+        String[] values = Utils.split(exportType);
+        List<CellDataType> result = new ArrayList<CellDataType>();
+
+        for (String value : values) {
+            if (Util.isEmptyStr(value)) {
+                continue;
+            }
+
+            CellDataType cellType = CellTypes.toExcelCellType(value);
+
+            if (cellType != null) {
+                result.add(cellType);
+            }
+        }
+
+        return (CellDataType[]) result.toArray();
+	}
+
+	public String getId() {
+		return id;
+	}
+	public String getParentId() {
+		return parentId;
+	}
+	public String getFromField() {
+		return fromField;
+	}
+	public String getToField() {
+		return toField;
+	}
+	public boolean isInsertIgnore() {
+		return insertIgnore;
+	}
+	public boolean isUpdateIgnore() {
+		return updateIgnore;
+	}
+	
+	public CellDataType[] getExportType() {
+		return exportType;
+	}
+	
+}
diff --git a/src/frame/file/office/IOMappingItemRuntime.java b/src/frame/file/office/IOMappingItemRuntime.java
new file mode 100644
index 0000000..024c66e
--- /dev/null
+++ b/src/frame/file/office/IOMappingItemRuntime.java
@@ -0,0 +1,81 @@
+package frame.file.office;
+
+import org.apache.poi.ss.format.CellFormatType;
+
+import com.alibaba.druid.sql.ast.statement.SQLCommentStatement.Type;
+
+import frame.data.DataType;
+import frame.data.meta.EntityMeta;
+import frame.data.meta.Field;
+import frame.file.CellDataType;
+import frame.file.CellTypes;
+
+public class IOMappingItemRuntime {
+	 private IOMappingItem item;
+     private String fromField;
+     private DataType fromType;
+     private String toField;
+     private int toIndex;
+     private DataType toType;
+     
+     public IOMappingItemRuntime(IOMappingItem ioMappingItem, String fromField, Field fieldByFrom, String toField,  Field fieldByto) {
+    	 item = ioMappingItem;
+    	 this.fromField = fromField == null ? null : fromField.toLowerCase();
+
+         if (fieldByFrom != null) {
+             fromType = fieldByFrom.getDataType();
+         }
+         else {
+             fromType = null;
+         }
+         
+         //2. set to
+         this.toField = toField == null ? null : toField.toLowerCase();
+
+         if (fieldByto != null) {
+             toType = fieldByto.getDataType();
+         }
+         else {
+             toType = null;
+         }
+     }
+     
+     public CellDataType[] getExportType() {
+         if (item != null) {
+        	 CellDataType[] result = item.getExportType();
+
+             if (result != null) {
+                 return result;
+             }
+         }
+
+         CellDataType cellType = CellTypes.toExcelCellType(fromType);
+         return new CellDataType[] { cellType };
+     }
+     
+     public IOMappingItem getItem() {
+    	 return item;
+     }
+
+     public String getFromField() {
+    	 return fromField;
+     }
+
+
+     public DataType getFromType() {
+    	 return fromType;
+     }
+
+     public String getToField() {
+    	 return toField;
+     }
+
+     public int getToIndex() {
+    	 return toIndex;
+     }
+
+     public DataType getToType() {
+    	 return toType;
+     }
+     
+}
diff --git a/src/frame/file/office/IOMappingRuntime.java b/src/frame/file/office/IOMappingRuntime.java
new file mode 100644
index 0000000..24261d6
--- /dev/null
+++ b/src/frame/file/office/IOMappingRuntime.java
@@ -0,0 +1,90 @@
+package frame.file.office;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class IOMappingRuntime {
+	  
+	private List<IOMappingItemRuntime> InsertMappingRuntimeList;
+	private Map<String, IOMappingItemRuntime> InsertfromMap;
+    private Map<String, IOMappingItemRuntime> InserttoMap;
+    private List<IOMappingItemRuntime> updateMappingRuntimeList;
+    private Map<String, IOMappingItemRuntime> updatefromMap;
+    private Map<String, IOMappingItemRuntime> updatetoMap;
+      
+    public IOMappingRuntime(List<IOMappingItemRuntime> insertMappingRuntime, List<IOMappingItemRuntime> updateMappingRuntime) {
+    	InsertMappingRuntimeList = new ArrayList<IOMappingItemRuntime>();
+    	InsertfromMap = new HashMap<String, IOMappingItemRuntime>();
+    	InserttoMap = new HashMap<String, IOMappingItemRuntime>();
+    	updateMappingRuntimeList = new ArrayList<IOMappingItemRuntime>();
+    	updatefromMap = new HashMap<String, IOMappingItemRuntime>();
+    	updatetoMap = new HashMap<String, IOMappingItemRuntime>();
+    	
+    	for (IOMappingItemRuntime ioMappingItemRuntime : insertMappingRuntime) {
+			addItem(ioMappingItemRuntime, "insert");
+		}
+    	
+    	for (IOMappingItemRuntime ioMappingItemRuntime : updateMappingRuntime) {
+			addItem(ioMappingItemRuntime, "update");
+		}
+    }
+
+	private void addItem(IOMappingItemRuntime ioMappingItemRuntime, String type) {
+		// base,add
+		if ("insert".equalsIgnoreCase(type)) {
+			InsertMappingRuntimeList.add(ioMappingItemRuntime);
+			InsertfromMap.put(ioMappingItemRuntime.getFromField(), ioMappingItemRuntime);
+			InserttoMap.put(ioMappingItemRuntime.getToField(), ioMappingItemRuntime);
+		}
+		else if ("update".equalsIgnoreCase(type)) {
+			updateMappingRuntimeList.add(ioMappingItemRuntime);
+			updatefromMap.put(ioMappingItemRuntime.getFromField(), ioMappingItemRuntime);
+			updatetoMap.put(ioMappingItemRuntime.getToField(), ioMappingItemRuntime);
+		}
+		
+	}
+    
+	public boolean contaisFromField(String fromField, String type) {
+		boolean containsField = containsField(fromField, "from", type);
+        return containsField;
+    }
+	
+	public boolean contaisToField(String toField, String type) {
+		boolean containsField = containsField(toField, "to", type);
+        return containsField;
+    }
+	
+	private boolean containsField(String field, String directionType, String dataType) {
+		if (field == null) {
+			return false;
+		}
+		if ("insert".equalsIgnoreCase(dataType)) {
+			if ("from".equalsIgnoreCase(directionType)) {
+				return InsertfromMap.containsKey(field.toLowerCase());
+			}
+			else if ("to".equalsIgnoreCase(directionType)) {
+				return InserttoMap.containsKey(field.toLowerCase());
+			}
+		}
+		else if ("update".equalsIgnoreCase(dataType)) {
+			if ("from".equalsIgnoreCase(directionType)) {
+				return updatefromMap.containsKey(field.toLowerCase());
+			}
+			else if ("to".equalsIgnoreCase(directionType)) {
+				return updatetoMap.containsKey(field.toLowerCase());
+			}
+		}
+		
+		return false;
+	}
+
+	public List<IOMappingItemRuntime> getUpdateMappingRuntime() {
+		return updateMappingRuntimeList;
+	}
+
+	public List<IOMappingItemRuntime> getInsertMappingRuntime() {
+		return InsertMappingRuntimeList;
+	}
+}
diff --git a/src/frame/file/office/IOProcessor.java b/src/frame/file/office/IOProcessor.java
new file mode 100644
index 0000000..d50e719
--- /dev/null
+++ b/src/frame/file/office/IOProcessor.java
@@ -0,0 +1,41 @@
+package frame.file.office;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import frame.expression.VariantContext;
+import frame.file.IFileContext;
+import frame.file.UploadResult;
+
+public abstract class IOProcessor {
+	private List<IOHandler> ioHandlers;
+
+    public IOProcessor() {
+        ioHandlers = new ArrayList<IOHandler>();
+    }
+
+    public void execHandlers(UploadResult result, String eventCode) throws Exception {
+    	IFileContext context = createContext(result);
+
+    	 for(IOHandler handler : ioHandlers) {
+            if (handler.equalEvent(eventCode)) {
+                handler.exec(result, context);
+            }
+        }
+    }
+
+    public void execHandlers(UploadResult result) throws Exception {
+    	IFileContext context = createContext(result);
+
+        for(IOHandler handler : ioHandlers) {
+            result.addMessage("杩涜鏁版嵁澶勭悊锛�" + handler.getSqlName());
+            handler.exec(result, context);
+        }
+    }
+
+    public void addHandler(IOHandler handler) {
+        ioHandlers.add(handler);
+    }
+    
+    public abstract IFileContext createContext(UploadResult result);
+}
diff --git a/src/frame/file/processor/Monitor.java b/src/frame/file/processor/Monitor.java
new file mode 100644
index 0000000..42395cc
--- /dev/null
+++ b/src/frame/file/processor/Monitor.java
@@ -0,0 +1,16 @@
+package frame.file.processor;
+
+public class Monitor {
+	private static Processor engineProgressor = new Processor();
+    private static Processor downloadProgressor = new Processor();
+
+
+    public static Processor getEngineProgressor() {
+        return engineProgressor;
+    }
+
+    public static Processor getDownloadProgressor() {
+        return downloadProgressor;
+    }
+
+}
diff --git a/src/frame/file/processor/Phase.java b/src/frame/file/processor/Phase.java
new file mode 100644
index 0000000..bfb93e1
--- /dev/null
+++ b/src/frame/file/processor/Phase.java
@@ -0,0 +1,44 @@
+package frame.file.processor;
+
+import java.util.Stack;
+
+public class Phase {
+	private String code;
+    private String name;
+    private int no;
+    private String noString;
+
+    public Phase(String code, String name) {
+        this.code = code;
+        this.name = name;
+        this.no = 1;
+        this.noString = "1.";
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setNo(Phase priorPhase, Stack<Phase> parents) {
+        if (priorPhase != null) {
+            no = priorPhase.no + 1;
+        }
+
+        noString = "";
+
+        for (Phase parent : parents) {
+            noString = parent.no + "." + noString;
+        }
+
+        noString = noString + no + ".";
+    }
+
+    public String getNoString() {
+        return noString;
+    }
+
+}
diff --git a/src/frame/file/processor/Processor.java b/src/frame/file/processor/Processor.java
new file mode 100644
index 0000000..279ede1
--- /dev/null
+++ b/src/frame/file/processor/Processor.java
@@ -0,0 +1,198 @@
+package frame.file.processor;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Stack;
+
+public class Processor {
+	private String taskName;
+    private Stack<Phase> phaseStack;
+    private List<String> messageList;
+    private Phase priorPhase;
+
+    private long max;
+    private long min;
+    private long step;
+    private long position;
+    private long stepBuffer;
+    private String stepMessage;
+
+    public Processor() {
+        messageList = new ArrayList<String>(100);
+        phaseStack = new Stack<Phase>();
+
+        max = 0;
+        min = 0;
+        step = 0;
+        position = 0;
+        stepBuffer = 0;
+        stepMessage = "0%--------0/0";
+    }
+
+    public void clear() {
+        priorPhase = null;
+        phaseStack.clear();
+        clearMessage();
+        clearStep();
+    }
+
+    public void clearStep() {
+        max = 0;
+        min = 0;
+        step = 0;
+        position = 0;
+        stepBuffer = 0;
+        stepMessage = "0%--------0/0";
+    }
+
+    public void stepIt() {
+        if (position < max) {
+            position++;
+            stepBuffer++;
+
+            if (stepBuffer >= step) {
+                double percent = position * 100 / max;
+                stepBuffer = 0;
+                stepMessage = Math.round(percent) + "%" + "--------" + position + "/" + max;
+            }
+        }
+        else {
+            stepMessage = "100%" + "--------" + max + "/" + max;
+        }
+    }
+
+    public void stepIt(int aStep) {
+        if (position < max) {
+            position = Math.min(position + aStep, max);
+            stepBuffer = stepBuffer + aStep;
+
+            if (stepBuffer >= step) {
+                double percent = position * 100 / max;
+                stepBuffer = 0;
+                stepMessage = Math.round(percent) + "%" + "--------" + position + "/" + max;
+            }
+        }
+        else {
+            stepMessage = "100%" + "--------" + max + "/" + max;
+        }
+    }
+
+    public long getMax() {
+        return max;
+    }
+
+    public void setMax(long max) {
+        clearStep();
+        this.max = max;
+    }
+
+    public long getMin() {
+        return min;
+    }
+
+    public void setMin(int min) {
+        this.min = min;
+    }
+
+    public String getStepMsg() {
+        return stepMessage;
+    }
+
+    public void newTask(String name) {
+        taskName = name;
+	
+        clearMessage();
+        clearStep();
+	
+        Date datetime = new Date();
+        appendLine(name + "寮�濮�..." + datetime);
+    }
+
+    public void endTask() {
+        appendLine(taskName + "缁撴潫");
+    }
+
+    public void newPhase(String code, String phaseName) {
+        Phase phase = new Phase(code, phaseName);
+        phase.setNo(priorPhase, phaseStack);
+
+        String indent = "";
+        for (int i = 0; i < phaseStack.size(); i++) {
+            indent = indent + "&nbsp;&nbsp;&nbsp;&nbsp;";
+        }
+
+        String title = indent + phase.getNoString() + phaseName;
+        appendLine(title);
+
+        phaseStack.push(phase);
+        priorPhase = null;
+    }
+
+    public void endPhase() {
+        clearStep();
+        priorPhase = phaseStack.pop();
+    }
+
+    public void clearMessage() {
+        messageList.clear();
+    }
+
+    private void appendLine(String message) {
+        if (message != null) {
+            messageList.add(message);
+        }
+    }
+
+    public void appendMesage(String message) {
+        String indent = "";
+        for (int i = 0; i <= phaseStack.size(); i++) {
+            indent = indent + "&nbsp;&nbsp;&nbsp;&nbsp;";
+        }
+
+        messageList.add(indent + message);
+    }
+
+    public void appendInlineMessage(String message) {
+        if (message != null) {
+            if (messageList.isEmpty()) {
+                messageList.add(message);
+                return;
+            }
+
+            int max = messageList.size() - 1;
+            String prior = messageList.get(max);
+            prior = prior + "......" + message;
+
+            messageList.remove(max);
+            messageList.add(prior);
+        }
+    }
+
+    public void setStepName(String step) {
+        messageList.add(step);
+    }
+
+    public List<String> getMessageList() {
+        return messageList;
+    }
+
+    public void terminate(String error) {
+        messageList.add(error);
+    }
+
+    public Boolean isEmpty() {
+        return messageList.size() == 0;
+    }
+
+    public List<Phase> getCurrentPhases() {
+	    List<Phase> resultList = new ArrayList<Phase>();
+	
+	    for (Phase phase : phaseStack) {
+		    resultList.add(phase);
+	    }
+	
+	    return resultList;
+    }
+
+}
diff --git a/src/frame/object/data/DataObject.java b/src/frame/object/data/DataObject.java
new file mode 100644
index 0000000..38901fc
--- /dev/null
+++ b/src/frame/object/data/DataObject.java
@@ -0,0 +1,210 @@
+package frame.object.data;
+
+import java.util.List;
+import java.util.Set;
+
+import frame.data.DataLink;
+import frame.data.DataType;
+import frame.data.Entity;
+import frame.data.EntitySet;
+import frame.data.IDataProvider;
+import frame.data.Page;
+import frame.expression.VariantRequestParams;
+import frame.object.http.HttpObject;
+import frame.persist.NamedSQL;
+import frame.persist.Result;
+import frame.persist.SQLCreator;
+import frame.persist.SQLRunner;
+
+
+public class DataObject extends HttpObject implements IDataProvider {
+
+	protected String dataName;
+	private String operator;
+	
+	
+	@Override
+	protected void publishMethod() {
+		addMethod("getDataSet");
+		addMethod("getSetByPage");
+		addMethod("getComboboxDataSet");
+		addMethod("procedure");
+		addMethod("getLine");
+		addMethod("newObject");
+		addMethod("addLine");
+		addMethod("deleteById");
+		addMethod("getCount");
+	}
+
+	public void getDataSet() throws Exception {
+		Filter filter = new Filter(onlineUser.getUserRight(), dataPool);
+		OrderBy orderBy = new OrderBy(dataPool);
+		
+		EntitySet entitySet = new EntitySet(dataName);
+		entitySet.loadDB(filter, orderBy);
+		
+		resultPool.addValue(entitySet);
+	}
+	
+	public void getSetByPage() throws Exception {
+		Filter filter = new Filter(onlineUser.getUserRight(), dataPool);
+		OrderBy orderBy = new OrderBy(dataPool);
+		
+		EntitySet entitySet = new EntitySet(dataName);
+		
+		int totalCount = entitySet.getDBCount(filter);
+		Page page = new Page(totalCount, dataPool);
+		
+		entitySet.loadDB(filter, page, orderBy);
+
+		resultPool.addValue("page", page);
+		resultPool.addValue(entitySet);
+	}
+	
+	public void getComboboxDataSet() throws Exception {
+		Filter filter = new Filter(onlineUser.getUserRight(), dataPool);
+		OrderBy orderBy = new OrderBy(dataPool);
+		
+		EntitySet entitySet = new EntitySet(dataName);
+		entitySet.loadDB(filter, orderBy);
+		
+		resultPool.addValue(entitySet);
+	}
+
+	public void procedure() throws Exception {
+		DataType returnType = path.getReturnType();
+
+		NamedSQL namedSQL = NamedSQL.getInstance(operator);
+		namedSQL.setReturnType(returnType);
+		
+		//set parameter for first time
+		Set<String> pageVariants = Page.getVarinatNameSet();
+		boolean reset = DataLink.moveOnConsumer(this, namedSQL, pageVariants);
+		
+		//set parameter for second time
+		Page page = null;
+		if (reset) {
+			int count = getProcedureDataCount(namedSQL); 
+			page = new Page(count, dataPool);
+			
+			DataLink.moveOnProvider(page, namedSQL);
+		}
+
+		Result result = namedSQL.exec();
+		resultPool.addValue(result.getValue());
+		
+		if (page != null) {
+			resultPool.addValue("page", page);
+		}
+	}
+	
+	public void getLine() throws Exception {
+		Id id = getId();
+		
+		if (id.isEmpty()) {
+			resultPool.error("empty id");
+			return;
+		}
+		
+		Entity entity = new Entity(dataName);
+		entity.loadDB(id);
+		
+		resultPool.addValue(entity);
+	}
+	
+	public void newObject() throws Exception {
+		Entity entity = new Entity(dataName);
+		
+		Initializer initializer = InitializerContainer.get(dataName);
+		initializer.exec(new VariantRequestParams(request), entity);
+		
+		resultPool.addValue("line", entity);
+	}
+	
+	public void addLine() throws Exception {
+		Entity entity = new Entity(dataName);
+		
+		Initializer initializer = InitializerContainer.get(dataName);
+		initializer.exec(new VariantRequestParams(request), entity);
+		DataLink.moveOnConsumer(dataPool, entity);
+		
+		entity.insertDB();
+		
+		resultPool.addValue("line", entity);
+	}
+	
+	public void saveLine() throws Exception {
+		Entity entity = new Entity(dataName);
+		DataLink.moveOnConsumer(dataPool, entity);
+
+		entity.saveDB();
+	}
+	
+	public void deleteById() throws Exception {
+		Id id = getId();
+		
+		if (id.isEmpty()) {
+			resultPool.error("empty id");
+			return;
+		}
+		
+		Entity entity = new Entity(dataName);
+		entity.set("id", id.getValue());
+		
+		entity.deleteDB();
+	}
+	
+	public void getCount() throws Exception {
+		Filter filter = new Filter(onlineUser.getUserRight(), dataPool);
+		
+		Entity entity = new Entity(dataName);
+		int count = entity.getDBCount(filter);
+		
+		resultPool.addValue(count);
+	}
+	
+	protected Filter getFilter() {
+		Filter filter = new Filter(onlineUser.getUserRight(), dataPool);
+		return filter;
+	}
+	
+	protected OrderBy getOrderBy() {
+		OrderBy orderBy = new OrderBy(dataPool);
+		return orderBy;
+	}
+	
+	protected Id getId() {
+		Id id = new Id(dataPool);
+		return id;
+	}
+	
+	private int getProcedureDataCount(NamedSQL namedSQL) throws Exception {
+		String sql = namedSQL.getSQL();
+		sql = SQLCreator.deletePageLimit(sql);
+		sql = "select count(1) from (" + sql + ") tempTbl";
+		
+		namedSQL = new NamedSQL("getCount", sql);
+		int count = SQLRunner.getInteger(namedSQL);
+		
+		return count;
+	}
+
+	@Override
+	public List<String> getDataNameList() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean containsData(String name) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public Object getDataValue(String name) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/src/frame/object/data/Filter.java b/src/frame/object/data/Filter.java
new file mode 100644
index 0000000..da2c053
--- /dev/null
+++ b/src/frame/object/data/Filter.java
@@ -0,0 +1,31 @@
+package frame.object.data;
+
+import frame.util.ContentBuilder;
+import frame.util.Util;
+
+public class Filter {
+
+	private String value;
+	
+	public Filter(IFilterSegmentProvider ...segmentProviders) {
+		ContentBuilder result = new ContentBuilder(" and ");
+		
+		for (int i = 0; i < segmentProviders.length; i++) {
+			IFilterSegmentProvider segmentProvider = segmentProviders[i];
+			String segment = segmentProvider.getFilterValue();
+			
+			if (Util.isEmptyStr(segment)) {
+				segment = "1=1";
+			}
+			
+			result.append("(").append(segment).append(")");
+		}
+		
+		value = result.toString();
+	}
+
+	public String getValue() {
+		return value;
+	}
+	
+}
diff --git a/src/frame/object/data/FilterSegment.java b/src/frame/object/data/FilterSegment.java
new file mode 100644
index 0000000..6f563a9
--- /dev/null
+++ b/src/frame/object/data/FilterSegment.java
@@ -0,0 +1,5 @@
+package frame.object.data;
+
+public class FilterSegment {
+
+}
diff --git a/src/frame/object/data/IFilterSegmentProvider.java b/src/frame/object/data/IFilterSegmentProvider.java
new file mode 100644
index 0000000..1170a94
--- /dev/null
+++ b/src/frame/object/data/IFilterSegmentProvider.java
@@ -0,0 +1,7 @@
+package frame.object.data;
+
+public interface IFilterSegmentProvider {
+
+	String getFilterValue();
+
+}
diff --git a/src/frame/object/data/Id.java b/src/frame/object/data/Id.java
new file mode 100644
index 0000000..e490d9e
--- /dev/null
+++ b/src/frame/object/data/Id.java
@@ -0,0 +1,26 @@
+package frame.object.data;
+
+import frame.object.http.HttpDataPool;
+import frame.util.Util;
+
+public class Id {
+	
+	private String value;
+
+	public Id(HttpDataPool dataPool) {
+		value = dataPool.getString("id");
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public boolean isEmpty() {
+		return Util.isEmptyStr(value);
+	}
+
+	public String getQuotedValue() {
+		return Util.quotedStr(value);
+	}
+	
+}
diff --git a/src/frame/object/data/Initializer.java b/src/frame/object/data/Initializer.java
new file mode 100644
index 0000000..f501c3f
--- /dev/null
+++ b/src/frame/object/data/Initializer.java
@@ -0,0 +1,36 @@
+package frame.object.data;
+
+import frame.data.Entity;
+import frame.expression.VariantRequestParams;
+import frame.util.Util;
+
+public class Initializer {
+
+	public void exec(VariantRequestParams variantRequestParams, Entity entity) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public void loadDefaultValue(VariantRequestParams params) throws Exception {
+		String tableName = entityMeta.getName();
+		EntityConfig entityConfig = configContainer.get(tableName);
+		
+		if (entityConfig == null) {
+			set("id", Util.newShortGUID());
+			return;
+		}
+		
+		for (FieldConfig fieldConfig: entityConfig) {
+			String name = fieldConfig.getName();
+			
+			if (!entityMeta.contains(name)) {
+				continue;
+			}
+			
+			Object value = fieldConfig.getValue(params);
+			set(name, value);
+		}
+	}
+	
+
+}
diff --git a/src/frame/object/data/InitializerContainer.java b/src/frame/object/data/InitializerContainer.java
new file mode 100644
index 0000000..7dd9979
--- /dev/null
+++ b/src/frame/object/data/InitializerContainer.java
@@ -0,0 +1,10 @@
+package frame.object.data;
+
+public class InitializerContainer {
+
+	public static Initializer get(String dataName) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/src/frame/object/data/OrderBy.java b/src/frame/object/data/OrderBy.java
new file mode 100644
index 0000000..5ff1b1d
--- /dev/null
+++ b/src/frame/object/data/OrderBy.java
@@ -0,0 +1,24 @@
+package frame.object.data;
+
+import frame.data.DataPool;
+import frame.util.Util;
+
+public class OrderBy {
+
+	private String value;
+	private boolean empty;
+	
+	public OrderBy(DataPool dataPool) {
+		value = dataPool.getString("orderby");
+		empty = Util.isEmptyStr(value);
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public boolean isEmpty() {
+		return empty;
+	}
+	
+}
diff --git a/src/frame/object/http/HttpDataPool.java b/src/frame/object/http/HttpDataPool.java
new file mode 100644
index 0000000..6be2748
--- /dev/null
+++ b/src/frame/object/http/HttpDataPool.java
@@ -0,0 +1,25 @@
+package frame.object.http;
+
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+
+import frame.data.DataPool;
+
+public class HttpDataPool extends DataPool {
+
+	public HttpDataPool() throws Exception {
+		
+	}
+
+	public void load(HttpServletRequest request) throws Exception {
+		Enumeration<String> paramNames = request.getParameterNames();
+
+		while (paramNames.hasMoreElements()) {
+			String paramName = (String) paramNames.nextElement();
+			String value = request.getParameter(paramName);
+			add(paramName, value);
+		}
+	}
+	
+}
diff --git a/src/frame/object/http/HttpObject.java b/src/frame/object/http/HttpObject.java
new file mode 100644
index 0000000..1a64a90
--- /dev/null
+++ b/src/frame/object/http/HttpObject.java
@@ -0,0 +1,233 @@
+package frame.object.http;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+
+import frame.call.writer.EnvelopWriter;
+import frame.role.OnlineUser;
+import frame.role.UserRight;
+import frame.util.Util;
+
+public abstract class HttpObject {
+
+	protected static Logger logger;
+	protected HttpServletResponse response;
+	protected HttpServletRequest request;
+	protected OnlineUser onlineUser;
+	protected EnvelopWriter writer;
+	protected ResultPool resultPool;
+	protected HttpDataPool dataPool;
+	protected Path path ;
+	protected Map<String, Method> methodMap;
+	protected Map<String, Method> allMethodMap;
+	protected boolean fireReplay;
+
+	static {
+		logger = Logger.getLogger(HttpObject.class);
+	}
+
+	public HttpObject() {
+		methodMap = new HashMap<String, Method>();
+		allMethodMap = new HashMap<String, Method>();
+		fireReplay = true;
+
+		collectMethod();
+		publishMethod();
+	}
+
+	public void receive(String pathString) { //path涓� shortTarget
+		resultPool = new ResultPool();
+		
+		try {
+			path = new Path(pathString);
+			
+			if (!path.isValid()) {
+				writer.ReplyError("bad path:" + pathString);
+			}
+			
+			dataPool = new HttpDataPool();
+			dataPool.load(request);
+			
+			writer = new EnvelopWriter(request, response);
+			try {
+				if (onlineUser != null) {
+					try {
+						//1. check user right
+						UserRight userRight = onlineUser.getUserRight();
+								
+						if (!userRight.isValid(path)) {
+							resultPool.setInvalidUserRight(path);
+							return;
+						}
+						
+						//2. execute 
+						doReceive(path);
+					}
+					catch (Exception e) {
+						onError(e);
+					}
+				}
+				else {
+					writer.replayTimeout();
+				}
+
+				if (fireReplay) {
+					writer.replay(resultPool);
+					writer.flush();
+				}
+			}
+			catch (Exception e) {
+				String error = e.getClass().getName() + ": " + e.getMessage();
+				writer.ReplyError(error);
+				logger.error("ajax error: " + e);
+			}
+		}
+		catch (Exception e) {
+		}
+	}
+
+	protected void doReceive(Path path) throws Exception {
+		String lower = path.getOperator().toLowerCase();
+		Method method = methodMap.get(lower);
+		
+		if (method == null) {
+			method = methodMap.get("call");
+		}
+		
+		if (method != null) {
+			try {
+				beforeExecute();
+				method.invoke(this);
+			}
+			catch (InvocationTargetException e) {
+				Throwable throwable = e.getTargetException();
+
+				if (throwable == null) {
+					throw e;
+				}
+				else {
+					throw (Exception) throwable;
+				}
+			}
+		}
+		else {
+			resultPool.error("method not exists: " + path.getPathString());
+		}
+	}
+
+	protected void beforeExecute() throws Exception {
+
+	}
+
+	protected void onError(Exception e) throws Exception {
+		logger.error(e);
+		e.printStackTrace();
+	}
+
+	public HttpDataPool getDataPool() throws Exception {
+		return dataPool;
+	}
+
+	protected void collectMethod() {
+		Method[] methods = this.getClass().getDeclaredMethods();
+
+		for (Method one : methods) {
+			allMethodMap.put(one.getName().toLowerCase(), one);
+		}
+	}
+
+	protected void publishMethod() {
+
+	}
+
+	protected void addMethod(String name) {
+		if (name == null) {
+			return;
+		}
+
+		name = name.toLowerCase();
+		Method method = allMethodMap.get(name);
+
+		if (method != null) {
+			method.setAccessible(true);
+			methodMap.put(name, method);
+		}
+	}
+
+	protected String locateSQLVariant(String name) throws Exception {
+		String value = request.getParameter(name);
+
+		if (value != null && value.startsWith("@{")) {
+			name = value.substring(2, value.length() - 1);
+			value = getDefaultParameter(name);
+			return value;
+		}
+		else if (value != null) {
+			return value;
+		}
+
+		value = getDefaultParameter(name);
+
+		return value;
+	}
+	
+	protected String getDefaultParameter(String name) {
+		if ("userid".equalsIgnoreCase(name)) {
+			return onlineUser.getId();
+		}
+		else if ("rolecode".equalsIgnoreCase(name)) {
+			return onlineUser.getRoleCode();
+		}
+		else if ("username".equalsIgnoreCase(name)) {
+			return onlineUser.getName();
+		}
+		else if ("orgid".equalsIgnoreCase(name)) {
+			return onlineUser.getOrgId();
+		}
+		else if ("newid".equalsIgnoreCase(name)) {
+			return Util.newShortGUID();
+		}
+		else if ("newDate".equalsIgnoreCase(name)) {
+			return Util.DataTimeToString(new Date());
+		}
+		else if ("filter".equalsIgnoreCase(name)) {
+			return "1 = 1";
+		}
+
+		return null;
+	}
+
+	public HttpServletRequest getRequest() {
+		return request;
+	}
+
+	public HttpServletResponse getResponse() {
+		return response;
+	}
+	
+	public OnlineUser getOnlineUser() {
+		return onlineUser;
+	}
+	
+	public ResultPool getResultPool() {
+		return resultPool;
+	}
+
+
+	public Path getPath() {
+		return path;
+	}
+
+	public EnvelopWriter getWriter() {
+		return writer;
+	}
+
+}
diff --git a/src/frame/object/http/JsonItem.java b/src/frame/object/http/JsonItem.java
new file mode 100644
index 0000000..28418c1
--- /dev/null
+++ b/src/frame/object/http/JsonItem.java
@@ -0,0 +1,5 @@
+package frame.object.http;
+
+public class JsonItem extends ResultItem {
+
+}
diff --git a/src/frame/object/http/ObjectItem.java b/src/frame/object/http/ObjectItem.java
new file mode 100644
index 0000000..dc8283e
--- /dev/null
+++ b/src/frame/object/http/ObjectItem.java
@@ -0,0 +1,5 @@
+package frame.object.http;
+
+public class ObjectItem extends ResultItem {
+
+}
diff --git a/src/frame/object/http/Path.java b/src/frame/object/http/Path.java
new file mode 100644
index 0000000..4a7e65c
--- /dev/null
+++ b/src/frame/object/http/Path.java
@@ -0,0 +1,188 @@
+package frame.object.http;
+
+import java.net.URLDecoder;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import frame.data.DataType;
+
+public class Path {
+	
+	protected String pathString;
+	protected String[] pathArray;
+	private String objectName;
+	private String operator;
+	private String dataName;
+	private DataType returnType;
+	private boolean valid;
+
+	private static Set<String> pageTypes;
+	public static int contextLength;
+	private HttpServletRequest request;
+	private String uri;
+	private String target;  //鍘绘帀椤圭洰鍚嶏紝鍘绘帀root鏍囩锛屽苟浠�/寮�澶�
+	private String shortTarget;  //鍘绘帀椤圭洰鍚嶏紝鍘绘帀root鏍囩锛屼笉浠�/寮�澶�
+	private String suffix;  //璇锋眰鍚庣紑锛屾病鐢ㄥ垯涓篤irtualPath璺緞锛屾湁鍒欎负Resource璺緞
+	private String leaf;  ////target鐨勬渶鍚庝竴鎴�
+	private String parent;  //target鐨勭涓�鎴�
+	private RequestType type;  //VirtualPath銆丷esource
+
+	static {
+		pageTypes = new HashSet<String>();
+		pageTypes.add(".html");
+		pageTypes.add(".htm");
+		pageTypes.add(".jsp");
+	}
+
+	
+	public Path(HttpServletRequest request) {
+		this.request = request;
+
+		// /sfez/xxx/xxx/xx.html,uri鏄笉甯﹁姹傚弬鏁扮殑锛屽嵆涓嶄細甯︼紵xxx=xxx
+		uri = request.getRequestURI();
+		
+		try {
+			uri = URLDecoder.decode(uri, "UTF-8");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 1. delete parameters(娌$敤)
+		int last = uri.length();
+		int pos_param = uri.indexOf("?");
+		if (pos_param > 0) {
+			last = pos_param;
+		}
+
+		
+		target = uri.substring(contextLength, last);
+
+		// 2. root
+		if ("/".equals(target)) {
+			type = RequestType.VirtualPath;
+			return;
+		}
+
+		// 3. find root
+		int pos = target.lastIndexOf("/root/");
+		if (pos >= 0) {
+			target = target.substring(pos + "/root/".length());
+		}
+
+		if (target.charAt(0) != '/') {
+			target = "/" + target;
+		}
+
+		// 4. resource
+		int pos_dot = target.lastIndexOf(".");
+
+		if (pos_dot > 0) {
+			suffix = target.substring(pos_dot);
+			type = RequestType.Resource;
+		} else {
+			type = RequestType.VirtualPath;
+		}
+
+		int pos_begin = target.indexOf("/", 1);
+		if (pos_begin > 0) {
+			parent = target.substring(0, pos_begin);
+		}
+
+		int pos_end = target.lastIndexOf("/");
+		if (pos_end >= pos_begin) {
+			leaf = target.substring(pos_end);
+		}
+
+		shortTarget = target.substring(1);
+	}
+
+	public String getSuffix() {
+		return suffix;
+	}
+
+	public String getTarget() {
+		return target;
+	}
+
+	public String getShortTarget() {
+		return shortTarget;
+	}
+
+	public String getLeaf() {
+		return leaf;
+	}
+
+	public String getParent() {
+		return parent;
+	}
+
+	public HttpServletRequest getRequest() {
+		return request;
+	}
+
+	public String getURI() {
+		return uri;
+	}
+
+	public RequestType getType() {
+		return type;
+	}
+
+	@Override
+	public String toString() {
+		return uri;
+	}
+	
+	public Path(String pathString) {
+		this.pathString = pathString;
+		String[] paths = pathString.split("/");
+		int length = paths.length;
+		
+		pathArray = paths;
+		valid = length >= 2;
+		
+		if (valid) {
+			objectName = paths[0];
+			operator = paths[1];
+			
+			if (length > 2) {
+				dataName = paths[2];
+				
+				if (length > 3) {
+					returnType = DataType.valueOfString(paths[3]);
+				}
+			}
+		}
+	}
+
+	public String getObjectName() {
+		return objectName;
+	}
+
+	public String getOperator() {
+		return operator;
+	}
+
+	public String getDataName() {
+		return dataName;
+	}
+
+	public String[] getPathArray() {
+		return pathArray;
+	}
+	
+	public DataType getReturnType() {
+		return returnType;
+	}
+	
+	public String getPathString() {
+		return pathString;
+	}
+
+	public boolean isValid() {
+		return valid;
+	}
+
+}
diff --git a/src/frame/object/http/RequestType.java b/src/frame/object/http/RequestType.java
new file mode 100644
index 0000000..bc33f96
--- /dev/null
+++ b/src/frame/object/http/RequestType.java
@@ -0,0 +1,7 @@
+package frame.object.http;
+
+public enum RequestType {
+
+	Resource, VirtualPath;
+	
+}
diff --git a/src/frame/object/http/ResultItem.java b/src/frame/object/http/ResultItem.java
new file mode 100644
index 0000000..57ffa8d
--- /dev/null
+++ b/src/frame/object/http/ResultItem.java
@@ -0,0 +1,39 @@
+package frame.object.http;
+
+import frame.call.writer.IBeanWriter;
+
+public class ResultItem {
+
+	private String name;
+	private Object value;
+	private IBeanWriter beanWriter;
+	
+	public ResultItem() {
+		
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public void setValue(Object value) {
+		this.value = value;
+	}
+
+	public void setBeanWriter(IBeanWriter beanWriter) {
+		this.beanWriter = beanWriter;
+	}
+
+	public IBeanWriter getBeanWriter() {
+		return beanWriter;
+	}
+	
+}
diff --git a/src/frame/object/http/ResultPool.java b/src/frame/object/http/ResultPool.java
new file mode 100644
index 0000000..3a62625
--- /dev/null
+++ b/src/frame/object/http/ResultPool.java
@@ -0,0 +1,150 @@
+package frame.object.http;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import frame.call.writer.IBeanWriter;
+
+public class ResultPool {
+
+	private boolean success;
+	private String errorCode;
+	private String errorMessage;
+	private String code;
+	private String message;
+	private List<ResultItem> itemList;
+	private String json;
+
+	public ResultPool() {
+		success = true; // 鍒涘缓瀵硅薄鏃跺嵆涓簍rue锛屽彧瑕佷笉浜轰负璁剧疆false锛屽氨涓�鐩磘rue
+		itemList = new ArrayList<ResultItem>();
+	}
+
+	public void success() {
+		success = true;
+	}
+
+	public void error(String message) {
+		error(null, message);
+	}
+
+	public void error(String code, String message) {
+		success = false;
+		errorCode = code;
+		errorMessage = message;
+	}
+
+	public void setMessage(String code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+	
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public boolean isSuccess() {
+		return success;
+	}
+
+	public String getErrorCode() {
+		return errorCode;
+	}
+
+	public String getErrorMessage() {
+		return errorMessage;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+
+	public void addValue(Object value) {// 娣诲姞鍖垮悕缁撴灉锛屽悕瀛楃敤瀵硅薄鐨勭畝鍗曠被鍚�
+		if (value == null) {
+			return;
+		}
+
+		String name = value.getClass().getSimpleName();
+		addValue(name, value);
+	}
+
+	public void addValue(Object name, Object value) {
+		if (name == null) {
+			addValue(value);
+		}
+
+		ResultItem resultItem = createResultItem(name, ObjectItem.class);
+		resultItem.setValue(value);
+	}
+	
+	public void addValue(Object name, Object value, IBeanWriter beanWriter) {
+		String nameStr = String.valueOf(name);
+		
+		if (nameStr == null) {
+			nameStr = "list";
+		}
+		
+		ResultItem resultItem = createResultItem(name, ObjectItem.class);
+		resultItem.setValue(value);
+		resultItem.setBeanWriter(beanWriter);
+	}
+	
+	public void addJson(Object name, String json) {
+		if (json == null) {
+			json = "null";
+		}
+		
+		ResultItem resultItem = createResultItem(name, JsonItem.class);
+		resultItem.setValue(json);
+	}
+
+	public boolean isJson() {
+		return json != null;
+	}
+	
+	public void setJson(String json) {
+		this.json = json;
+	}
+	
+	public String getJson() {
+		return json;
+	}
+
+	public List<ResultItem> getItemList() {
+		return itemList;
+	}
+	
+	private ResultItem createResultItem(Object name, Class<? extends ResultItem> clazz) {
+		String nameString = String.valueOf(name);
+		ResultItem resultItem = null;
+
+		for (ResultItem item : itemList) {
+			if (item.getName().equalsIgnoreCase(nameString)) {
+				resultItem = item;
+				break;
+			}
+		}
+
+		if (resultItem == null) {
+			try {
+				resultItem = clazz.newInstance();
+				resultItem.setName(nameString);
+				itemList.add(resultItem);
+			} 
+			catch (Exception e) {
+			}
+		}
+		
+		return resultItem;
+	}
+
+	public void setInvalidUserRight(Path path) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
diff --git a/src/frame/persist/ConnectionManager.java b/src/frame/persist/ConnectionManager.java
new file mode 100644
index 0000000..a3afeb6
--- /dev/null
+++ b/src/frame/persist/ConnectionManager.java
@@ -0,0 +1,79 @@
+package frame.persist;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.apache.log4j.Logger;
+
+import com.alibaba.druid.pool.DruidDataSource;
+
+import frame.role.Scenario;
+import frame.util.MapList;
+
+
+public class ConnectionManager {
+
+	private static Logger logger;
+	private static MapList<NamedDataSource> dataSourceList;
+	private static NamedDataSource defaultDataSource;
+	private static NamedDataSource activeDataSource;
+	
+	static {
+		logger = Logger.getLogger(ConnectionManager.class);
+		dataSourceList = new MapList<NamedDataSource>();
+	}
+
+	public static Connection createConnection() {
+		try {
+			if (activeDataSource != null) {
+				return activeDataSource.getConnection();
+			}
+			
+			Scenario scenario = ScenarioContainer.getActiveScenario();
+			
+			if (scenario == null) {
+				return defaultDataSource.getConnection();
+			}
+			
+			DataSource dataSource = scenario.getDataSource();
+			return dataSource.getConnection();
+		} 
+		catch (SQLException e) {
+			logger.error(e);
+			return null;
+		}
+	}
+	
+	public static void appendDataSource(NamedDataSource dataSource) throws SQLException {
+		String name = dataSource.getName();
+		
+		if (name == null) {
+			return;
+		}
+		
+		dataSourceList.add(name, dataSource);
+        
+        if (defaultDataSource == null) {
+        	defaultDataSource = dataSource;
+        }
+	}
+
+	public static NamedDataSource getDataSource(String code) {
+		if (code == null) {
+			return null;
+		}
+		
+		return dataSourceList.get(code);
+	}
+
+	public static List<NamedDataSource> getDataSourceList() {
+		return dataSourceList.getItemList();
+	}
+
+	public static void setActiveSource(NamedDataSource dataSource) {
+		activeDataSource = dataSource;
+	}
+}
diff --git a/src/frame/persist/DataCenter.java b/src/frame/persist/DataCenter.java
new file mode 100644
index 0000000..b4cae2e
--- /dev/null
+++ b/src/frame/persist/DataCenter.java
@@ -0,0 +1,81 @@
+package frame.persist;
+
+import frame.util.Util;
+
+
+
+public class DataCenter {
+
+	public static int Count_BatchLoad = 10000;
+	public static int Count_BatchSave = 10000;
+	
+	public static String SQL_Name_GetDataFilter = "getDataFilter";
+	public static String SQL_Name_UploadData = "uploadData";
+	public static String SQL_Name_WriteUploadRecord = "writeUploadRecord";
+	public static String SQL_Name_WriteUploadSuccess = "writeUploadSuccess";
+	public static String SQL_Name_ChangePassword = "changePassword";
+	public static String SQL_Name_EmptyTable = "emptyTable";
+	public static String SQL_Name_LoadOrgCode = "loadOrgCode";
+	public static String SQL_Name_LoadQRCode = "loadQRCode";
+	public static String SQL_Name_LoadUPNCode = "loadUPNCode";
+	public static String SQL_Name_LoadDocNo = "loadDocNo";
+	
+	public static String Param_Name_TableNameField = "table_name";
+	public static String Param_Name_DataLogTable = "data_log";
+	public static String Param_Name_LocalStamp = "localStamp";
+	public static String Param_Name_MaxStamp = "maxStamp";
+	public static String Param_Name_Schema = "schema";
+	public static String Param_Name_TableListId = "tableListId";
+	public static String Param_Name_CollectorId = "collectorId";
+	public static String Param_Name_OperatorField = "operatorField";
+	public static String Param_Name_RowIdField = "rowIdField";
+	
+	
+	public static String getDataFilter(String username) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance(SQL_Name_GetDataFilter);
+		namedSQL.setParam("username", username);
+		
+		String result = SQLRunner.getString(namedSQL);
+		return result;
+	}
+
+
+	public static String writeUploadRecord(String username, String filename, String path) throws Exception {
+		String id = Util.newShortGUID();
+		
+		NamedSQL namedSQL = NamedSQL.getInstance(SQL_Name_WriteUploadRecord);
+		namedSQL.setParam("id", id);
+		namedSQL.setParam("filename", filename);
+		namedSQL.setParam("path", path);		
+		namedSQL.setParam("username", username);
+		
+		SQLRunner.execSQL(namedSQL);
+		
+		return id;
+	}
+
+	public static void writeUploadSuccess(String id, int qty) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance(SQL_Name_WriteUploadSuccess);
+		namedSQL.setParam("id", id);
+		namedSQL.setParam("qty", qty);
+		
+		SQLRunner.execSQL(namedSQL);
+	}
+
+	public static void changePassword(String username, String password) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance(SQL_Name_ChangePassword);
+		namedSQL.setParam("username", username);
+		namedSQL.setParam("password", password);
+		
+		SQLRunner.execSQL(namedSQL);
+	}
+
+
+	public static void deleteData(String tableName) throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance(SQL_Name_EmptyTable);
+		namedSQL.setTableName(tableName);
+		
+		SQLRunner.execSQL(namedSQL);
+	}
+
+}
diff --git a/src/frame/persist/IDoubleSavable.java b/src/frame/persist/IDoubleSavable.java
new file mode 100644
index 0000000..221c2b6
--- /dev/null
+++ b/src/frame/persist/IDoubleSavable.java
@@ -0,0 +1,10 @@
+package frame.persist;
+
+import java.sql.PreparedStatement;
+
+
+public interface IDoubleSavable {
+
+	void save(PreparedStatement stmt1, PreparedStatement stmt2, Object ...agrs) throws Exception;
+	
+}
diff --git a/src/frame/persist/ILoadable.java b/src/frame/persist/ILoadable.java
new file mode 100644
index 0000000..c7711e1
--- /dev/null
+++ b/src/frame/persist/ILoadable.java
@@ -0,0 +1,9 @@
+package frame.persist;
+
+import java.sql.ResultSet;
+
+public interface ILoadable {
+
+	void load(ResultSet rslt, Object ...args) throws Exception;
+	
+}
diff --git a/src/frame/persist/IMetaDataLoader.java b/src/frame/persist/IMetaDataLoader.java
new file mode 100644
index 0000000..ff5da2b
--- /dev/null
+++ b/src/frame/persist/IMetaDataLoader.java
@@ -0,0 +1,11 @@
+package frame.persist;
+
+import java.sql.ResultSetMetaData;
+
+public interface IMetaDataLoader {
+
+	String getTableName();
+	
+	void load(ResultSetMetaData metaData) throws Exception;
+	
+}
diff --git a/src/frame/persist/ISavable.java b/src/frame/persist/ISavable.java
new file mode 100644
index 0000000..062fed4
--- /dev/null
+++ b/src/frame/persist/ISavable.java
@@ -0,0 +1,10 @@
+package frame.persist;
+
+import java.sql.PreparedStatement;
+
+public interface ISavable {
+
+	void save(PreparedStatement stmt, Object ...agrs) throws Exception;
+	
+	
+}
diff --git a/src/frame/persist/IStepLoadable.java b/src/frame/persist/IStepLoadable.java
new file mode 100644
index 0000000..309b853
--- /dev/null
+++ b/src/frame/persist/IStepLoadable.java
@@ -0,0 +1,15 @@
+package frame.persist;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public interface IStepLoadable {
+
+	boolean hasNextForLoad();
+	
+	void load(ResultSet rslt, Object ...args) throws Exception;
+
+	void setLoadParameters(PreparedStatement stmt) throws SQLException;
+	
+}
diff --git a/src/frame/persist/IStepSavable.java b/src/frame/persist/IStepSavable.java
new file mode 100644
index 0000000..300d493
--- /dev/null
+++ b/src/frame/persist/IStepSavable.java
@@ -0,0 +1,12 @@
+package frame.persist;
+
+import java.sql.PreparedStatement;
+
+
+public interface IStepSavable {
+
+	void save(PreparedStatement stmt, Object ...args) throws Exception;
+	
+	boolean hasNextForSave();
+	
+}
diff --git a/src/frame/persist/NamedDataSource.java b/src/frame/persist/NamedDataSource.java
new file mode 100644
index 0000000..ec412bb
--- /dev/null
+++ b/src/frame/persist/NamedDataSource.java
@@ -0,0 +1,18 @@
+package frame.persist;
+
+import com.alibaba.druid.pool.DruidDataSource;
+
+public class NamedDataSource extends DruidDataSource {
+
+	private static final long serialVersionUID = 1L;
+	private String name;
+	
+	public NamedDataSource(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+	
+}
diff --git a/src/frame/persist/NamedSQL.java b/src/frame/persist/NamedSQL.java
new file mode 100644
index 0000000..59600a3
--- /dev/null
+++ b/src/frame/persist/NamedSQL.java
@@ -0,0 +1,392 @@
+package frame.persist;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import frame.data.DataType;
+import frame.data.Entity;
+import frame.data.IDataConsumer;
+import frame.data.Page;
+import frame.data.meta.EntityMeta;
+import frame.data.meta.Field;
+import frame.expression.Expression;
+import frame.expression.IExpression;
+import frame.expression.VariantList;
+import frame.expression.VariantSegment;
+import frame.object.data.Filter;
+import frame.object.data.OrderBy;
+import frame.util.ContentBuilder;
+import frame.util.Util;
+
+
+public class NamedSQL implements Iterable<VariantSegment>, IExpression, IDataConsumer {
+
+	public static final String Param_Schema = "schema";
+	public static final String Param_TableName = "tablename";
+	public static final String Param_FieldNames = "fieldNames";
+	public static final String Param_FieldNameValues = "fieldNameValues";
+	public static final String Param_Values = "fieldValues";	
+	public static final String Param_PlaceHolders = "placeHolders";
+	public static final String Param_Filter = "filter";
+	public static final String Param_FieldNamePlaceHolders = "fieldNamePlaceHolders";
+	public static final String Param_KeyFieldName = "keyFieldName";
+	public static final String Param_OrderBy = "orderby";
+	
+	private static NamedSQLContainer namedSQLContainer;
+	
+	protected String name;
+	protected String sql;
+	protected DataType returnType;
+	protected Expression expression;
+	
+	static {
+		namedSQLContainer = NamedSQLContainer.getInstance();
+	}
+
+	private NamedSQL(String name) {
+		this.name = name;
+		returnType = DataType.Void;
+	}
+	
+	public NamedSQL(String name, String sql) throws Exception {
+		this.name = name;
+		this.sql = sql;
+		
+		parseSQL(sql);
+	}
+	
+	protected void parseSQL(String sql) throws Exception {
+		String lower = sql.toLowerCase();
+		
+		if (lower.indexOf("row_number()") > 0) {
+			sql = "select * from (" + sql + ")table_t where rownum > @{beginNo} and rownum <= @{endNo}";
+		}
+		
+		expression = new SQLCreator(sql);
+	}
+
+	public static NamedSQL[] getInstance(String[] names) throws Exception {
+		if (names == null) { return new NamedSQL[0]; };
+		
+		NamedSQL[] result = new NamedSQL[names.length];
+		
+		for (int i = 0; i < names.length; i++) {
+			result[i] = getInstance(names[i]);
+		}
+		
+		return result;
+	}
+	
+	public static NamedSQL getInstance(String name) throws Exception {
+		String condtion = SystemCondition.getFilterValue();
+		
+		NamedSQL result = namedSQLContainer.get(name, condtion);
+		
+		if (result == null) {
+			result = namedSQLContainer.get(name, null);
+		}
+		
+		if (result == null) {
+			throw new Exception("can not find named sql: " + name);
+		}
+		
+		result = result.newInstance();
+		return result;
+	}
+	
+	public NamedSQL newInstance() throws Exception {
+		NamedSQL instance = new NamedSQL(this.name);
+		instance.sql = this.sql;
+		instance.expression = this.expression.newInstance();
+		
+		return instance;
+	}
+
+	public String getSQL() throws Exception {
+		String result = expression.getString();
+		return result;
+	}
+	
+	public String getOriginalSql(){
+		return sql;
+	}
+
+	public Result exec() throws Exception {
+		Result result = SQLRunner.getResult(this);
+		return result;
+	}
+	
+	public NamedSQL setSchema(String schema) {
+		return setParam(Param_Schema, schema);
+	}
+
+	public NamedSQL setTableName(String tableName) {
+		return setParam(Param_TableName, tableName);
+	}
+
+	public NamedSQL setFieldNames(String names) {
+		return setParam(Param_FieldNames, names);
+	}
+	
+	public NamedSQL setFieldNames(EntityMeta tableMeta) {
+		StringBuilder result = new StringBuilder();
+		boolean empty = true;
+		
+		for (Field field: tableMeta) {
+			if (!empty) {
+				result.append(", ");
+			}
+			
+			result.append(field.getName());
+			
+			empty = false;
+		}
+		
+		return setParam(Param_FieldNames, result.toString());
+	}
+	
+	public NamedSQL setFieldNames(EntityMeta tableMeta, Entity entity) {
+		StringBuilder result = new StringBuilder();
+		boolean empty = true;
+		Field field;
+		
+		for (int i = 0; i < tableMeta.getFieldCount(); i++) {
+			if (entity.isEmptyValue(i)) {
+				continue;
+			}
+				
+			field = tableMeta.get(i);
+			
+			if (!empty) {
+				result.append(", ");
+			}
+
+			result.append(field.getName());
+			empty = false;
+		}
+		
+		return setParam(Param_FieldNames, result.toString());
+	}
+	
+	public NamedSQL setFieldNames(Collection<Field> fields) {
+		ContentBuilder result = new ContentBuilder();
+		
+		for (Field field: fields) {
+			result.append(field.getName(), ", ");
+		}
+		
+		return setParam(Param_FieldNames, result.toString());
+	}
+	
+	public NamedSQL setValues(Entity entity) throws Exception {
+		ContentBuilder result = new ContentBuilder();
+		int cnt = entity.getFieldCount();
+		
+		for (int i = 0; i < cnt; i++) {
+			if (entity.isEmptyValue(i)) {
+				continue;
+			}
+			
+			result.append(entity.getSQLString(i), ", ");
+		}
+		
+		return setParam(Param_Values, result.toString());
+	}
+	
+	public NamedSQL setQuotedFieldNames(EntityMeta tableMeta) {
+		ContentBuilder result = new ContentBuilder();
+		
+		for (Field field: tableMeta) {
+			result.append(Util.doubleQuotedStr(field.getName()), ", ");
+		}
+		
+		return setParam(Param_FieldNames, result.toString());
+	}
+
+	public NamedSQL setPlaceHolders(Collection<Field> fields) {
+		ContentBuilder result = new ContentBuilder();
+		int cnt = fields.size();
+		
+		for (int i = 0; i < cnt; i++) {
+			result.append("?", ", ");
+		}
+		
+		return setParam(Param_PlaceHolders, result.toString());
+	}
+	
+	public NamedSQL setPlaceHolders(String placeHolders) {
+		return setParam(Param_PlaceHolders, placeHolders);
+	}
+
+	public NamedSQL setFieldNamePlaceHolders(EntityMeta tableMeta) {
+		ContentBuilder result = new ContentBuilder();
+		
+		for (Field field: tableMeta) {
+			result.append(field.getName() + " = ? ", ", ");
+		}
+		
+		return setParam(Param_FieldNamePlaceHolders, result.toString());
+	}
+
+	public NamedSQL setKeyFieldName(EntityMeta tableMeta) throws Exception {
+		String keyName = tableMeta.getFiledName_Key();
+		return setParam(Param_KeyFieldName, keyName);		
+	}
+
+	public NamedSQL setKeyFieldName(String fieldName) throws Exception {
+		return setParam(Param_KeyFieldName, fieldName);			
+	}
+	
+	public NamedSQL setFilter(String filter) {
+		if (Util.isEmptyStr(filter)) {
+			filter = "1=1";
+		}
+		
+		return setParam(Param_Filter, filter);	
+	}
+
+	public NamedSQL setOrderBy(String orderby) {
+		return setParam(Param_OrderBy, orderby);	
+	}
+
+	public NamedSQL setFieldNameValues(Entity entity) throws Exception {
+		ContentBuilder result = new ContentBuilder();
+		
+		EntityMeta tableMeta = entity.getEntityMeta();
+		int cnt = tableMeta.getFieldCount();
+		
+		for (int i = 0; i < cnt; i++) {
+			if (entity.isEmptyValue(i)) {
+				continue;
+			}
+			
+			Field field = tableMeta.get(i);
+			result.append(field.getName() + "=" + entity.getSQLString(i), ", ");
+		}
+		
+		return setParam(Param_FieldNameValues, result.toString());
+	}
+
+	public NamedSQL setParam(String name, String value) {
+		if (value == null) {
+			return this;
+		}
+		
+		VariantSegment variant = expression.getVariant(name);
+		
+		if (variant != null) {
+			variant.setValue(value);
+		}
+		
+		return this;
+	}
+	
+	public NamedSQL setParam(String name, String value, String defaultValue) {
+		if (value == null) {
+			value = defaultValue;
+		}
+		
+		VariantSegment sqllVariant = expression.getVariant(name);
+		
+		if (sqllVariant != null) {
+			sqllVariant.setValue(value);
+		}
+		
+		return this;
+	}
+	
+	public NamedSQL setParam(String name, int value) {
+		String stringValue = String.valueOf(value);
+		return setParam(name, stringValue);
+	}
+	
+	public NamedSQL setParam(String name, BigDecimal value) {
+		String stringValue = value.toString();
+		return setParam(name, stringValue);		
+	}
+	
+	public NamedSQL setParam(String name, Date date) {
+		String stringValue = Util.toMySQLDateStr(date);
+		return setParam(name, stringValue);
+	}
+	
+	public NamedSQL setParam(String name, boolean value) {
+		String stringValue = Util.booleanToStr(value);
+		return setParam(name, stringValue);
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public DataType getReturnType() {
+		return returnType;
+	}
+
+	public void setReturnType(DataType dataType) {
+		this.returnType = dataType;
+	}
+	
+	public String getSQLString() throws Exception {
+		return expression.tryGetString(); 
+	}
+	
+	@Override
+	public String toString() {
+		return expression.getString();
+	}
+
+	@Override
+	public Iterator<VariantSegment> iterator() {
+		return expression.iterator();
+	}
+
+	public void clearVariantValues() {
+		expression.clearVariantValues();
+	}
+
+	public VariantList getVariantList() {
+		return expression.getVariantList();
+	}
+
+	public Expression getExpression() {
+		return expression;
+	}
+
+	public NamedSQL setFilter(Filter filter) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void setOrderBy(OrderBy orderBy) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public NamedSQL setPage(Page page) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<String> getDataNameList() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean containsData(String name) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public void setDataValue(String name, Object value) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
diff --git a/src/frame/persist/NamedSQLContainer.java b/src/frame/persist/NamedSQLContainer.java
new file mode 100644
index 0000000..e157a8e
--- /dev/null
+++ b/src/frame/persist/NamedSQLContainer.java
@@ -0,0 +1,71 @@
+package frame.persist;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import frame.util.Util;
+
+public class NamedSQLContainer {
+
+	private static NamedSQLContainer instance;
+	private Map<String, Map<String, NamedSQL>> contionalSQLMap;
+	
+	
+	private NamedSQLContainer() {
+		contionalSQLMap = new HashMap<String, Map<String, NamedSQL>>();
+	}
+	
+	public synchronized static NamedSQLContainer getInstance() {
+		if (instance == null) {
+			instance = new NamedSQLContainer();
+		}
+		
+		return instance;
+	}
+	
+	public NamedSQL get(String name, String condtion) {
+		if (name == null) {
+			return null;
+		}
+		
+		if (Util.isEmptyStr(condtion)) {
+			condtion = "empty";
+		}
+		
+		Map<String, NamedSQL> sqlmap = contionalSQLMap.get(condtion.toLowerCase());
+		if(sqlmap == null){
+			return null;
+		}
+		return sqlmap.get(name.toLowerCase());
+	}
+	
+	public void append(NamedSQL namedSQL, String condition) {
+		if (namedSQL == null) {
+			return;
+		}
+		
+		//1.
+		String name = namedSQL.getName();
+		if (name == null) {
+			return;
+		}
+		
+		//2.
+		if (Util.isEmptyStr(condition)) {
+			condition = "empty";
+		}
+		condition = condition.toLowerCase();
+		
+		//3.
+		Map<String, NamedSQL> sqlmap = contionalSQLMap.get(condition);
+
+		if (sqlmap == null) {
+			sqlmap = new HashMap<String, NamedSQL>();
+			contionalSQLMap.put(condition, sqlmap);
+		}
+		
+		//4.
+		sqlmap.put(name.toLowerCase(), namedSQL);
+	}
+
+}
diff --git a/src/frame/persist/NamedSQLLoader.java b/src/frame/persist/NamedSQLLoader.java
new file mode 100644
index 0000000..88b4153
--- /dev/null
+++ b/src/frame/persist/NamedSQLLoader.java
@@ -0,0 +1,125 @@
+package frame.persist;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import frame.config.Configer;
+import frame.config.Loader;
+import frame.util.Util;
+
+
+public class NamedSQLLoader extends Loader {
+
+	protected String Node_RootElements;
+	
+	private NamedSQLContainer sqlContainer;
+	
+	public NamedSQLLoader() throws FileNotFoundException {
+		path = Configer.getPath_SQLConfig();
+		sqlContainer = NamedSQLContainer.getInstance();
+		Node_RootElements = "dataSpace";
+	}
+	
+	@Override
+	public void load() {
+		File root = new File(path);
+		File[] files = root.listFiles();
+		
+		for (File config: files) {
+			if (!config.isFile()) {
+				continue;
+			}
+			
+			loadOneFile(config);
+		}
+	}
+	
+	public void loadOneFile(File file) {
+		try {
+			logger.debug("load sql file:" + file);
+			InputStream inputStream = new FileInputStream(file);
+			
+	        try {
+	    		SAXReader reader = new SAXReader();
+	    		reader.setValidation(false);
+	    			
+				Document doc = reader.read(inputStream);
+				Element root = doc.getRootElement();
+				
+				String active = root.attributeValue("active");
+				
+				if (!Util.isEmptyStr(active)) {
+					if (!Util.stringToBoolean(active)) {
+						return;
+					}
+				}
+					
+				loadRootElements(root);
+					
+			} catch (DocumentException e) {
+				logger.error("can not load sql file: " + file);
+				logger.error(e);
+			} finally {
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+		catch (Exception e) {
+			logger.error(e);
+		}
+	}
+	
+	protected void loadRootElements(Element root) throws Exception {
+		Iterator<?> iterator = root.elementIterator(Node_RootElements);
+		
+		while (iterator.hasNext()) {
+			Element element = (Element) iterator.next();	
+			loadOneRootElement(element);
+		}
+	}
+
+	protected void loadOneRootElement(Element element, Object ...args) throws Exception {
+		Iterator<?> sqlIterator = element.elementIterator();
+		
+		while (sqlIterator.hasNext()) {
+			Element statementElemnet = (Element) sqlIterator.next();
+			loadOneSQLElement(statementElemnet, args);
+		}
+	}
+
+	protected void loadOneSQLElement(Element element, Object ...args) throws Exception {
+		String name = element.attributeValue("name");	
+		
+		Iterator<?> iterator = element.elementIterator("condition");
+		boolean loaded = false;
+		
+		while (iterator.hasNext()) {
+			loaded = true;
+			
+			Element conditionElemnet = (Element) iterator.next();
+			String condition = conditionElemnet.attributeValue("value");
+			String sql = conditionElemnet.getTextTrim();
+			
+			NamedSQL namedSQL = new NamedSQL(name, sql);
+			sqlContainer.append(namedSQL, condition);
+		}
+		
+		if (!loaded) {
+			String sql = element.getTextTrim();
+			NamedSQL namedSQL = new NamedSQL(name, sql);
+			sqlContainer.append(namedSQL, null);
+		}
+	}
+
+}
diff --git a/src/frame/persist/Result.java b/src/frame/persist/Result.java
new file mode 100644
index 0000000..9f1257f
--- /dev/null
+++ b/src/frame/persist/Result.java
@@ -0,0 +1,81 @@
+package frame.persist;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import frame.data.DataType;
+import frame.data.Entity;
+import frame.data.EntitySet;
+import frame.data.Variant;
+
+
+public class Result {
+	
+	private DataType dataType;
+	private Variant variant;
+	private Object object;
+	
+	public Result() {
+		dataType = DataType.Void;
+	}
+
+	public void setValue(Integer value) {
+		variant = new Variant(value);
+		dataType = DataType.Int;  
+	}
+	
+	public void setValue(String value) {
+		variant = new Variant(value);
+		dataType = DataType.String;  
+	}
+
+	public void setValue(BigDecimal value) {
+		variant = new Variant(value);
+		dataType = DataType.Decimal;
+	}
+
+	public void setValue(Date value) {
+		variant = new Variant(value);
+		dataType = DataType.Date;
+	}
+
+	public void setValue(Entity value) {
+		object = value;
+		dataType = DataType.Entity; 
+	}
+
+	public void setValue(EntitySet value) {
+		object = value;
+		dataType = DataType.EntitySet;		
+	}
+
+	public DataType getDataType() {
+		return dataType;
+	}
+	
+	public Entity getEntity() {
+		return (Entity)object;
+	}
+
+	public EntitySet getEntitySet() {
+		return (EntitySet)object;
+	}
+
+	public String getString() {
+		return variant.getStringValue();
+	}
+	
+	public int getInt(int defaultValue) {
+		return variant.getIntValue(defaultValue);
+	}
+	
+	public BigDecimal getBigDecimal() {
+		return variant.getBigDecimalValue();
+	}
+	
+	public Variant getValue() {
+		return variant;
+	}
+
+
+}
diff --git a/src/frame/persist/SQLBuilder.java b/src/frame/persist/SQLBuilder.java
new file mode 100644
index 0000000..9aa9b1a
--- /dev/null
+++ b/src/frame/persist/SQLBuilder.java
@@ -0,0 +1,104 @@
+package frame.persist;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import frame.data.meta.EntityMeta;
+import frame.data.meta.Field;
+import frame.util.Util;
+
+
+public class SQLBuilder {
+
+	public static String getCreateTableSQL(EntityMeta tableMeta, String table, Collection<Field> fields) {
+		Set<Field> allFields = new HashSet<Field>();
+		
+		allFields.addAll(tableMeta.getFields());
+		
+		allFields.addAll(fields);
+		
+		return getCreateTableSQL(allFields, table);
+	}
+	
+	public static String getCreateTableSQL(EntityMeta tableMeta, String table) {
+		Set<Field> fields = new HashSet<Field>();
+		
+		fields.addAll(tableMeta.getFields());
+
+		return getCreateTableSQL(fields, table);
+	}
+	
+	private static String getCreateTableSQL(Collection<Field> fields, String table) {
+		if (table == null) {
+			return null;
+		}
+		
+		StringBuilder result = new StringBuilder();
+		result.append("CREATE TABLE ").append(table.toUpperCase()).append("(");
+		boolean empty = true;
+		
+		for (Field field: fields) {
+			if (!empty) {
+				result.append(", ");
+			}
+			
+			String name = field.getName();
+			result.append(Util.doubleQuotedStr(name.toUpperCase())).append(" ");
+			result.append(field.getSQLTypeCode());
+			
+			empty = false;
+		}
+		
+		result.append(")");
+		
+		return result.toString();		
+	}
+
+	public static String getModifyTableSQL(List<Field> fieldList, String table) {
+		StringBuilder result = new StringBuilder();
+		result.append("ALTER TABLE ").append(table.toUpperCase()).append(" ADD (");
+		boolean empty = true;
+		
+		for (Field field: fieldList) {
+			if (!empty) {
+				result.append(", ");
+			}
+			
+			result.append(field.getName().toUpperCase()).append(" ");
+			result.append(field.getSQLTypeCode()).append(field.getSQLNullCode());
+			
+			empty = false;
+		}
+		
+		result.append(")");
+		
+		return result.toString();
+	}
+
+	public static String getCreateIndexSQL(String table, String[] keyFields) {
+		if (table == null) {
+			return null;
+		}
+		
+		StringBuilder result = new StringBuilder();
+		result.append("CREATE UNIQUE INDEX ").append("IDX_").append(table.toUpperCase());
+		result.append(" ON ").append(table).append(" (");
+		
+		boolean empty = true;
+		
+		for (String field: keyFields) {
+			if (!empty) {
+				result.append(", ");
+			}
+			
+			result.append(field);
+			empty = false;
+		}
+		
+		result.append(")");
+		
+		return result.toString();
+	}
+}
diff --git a/src/frame/persist/SQLCreator.java b/src/frame/persist/SQLCreator.java
new file mode 100644
index 0000000..b8f8f40
--- /dev/null
+++ b/src/frame/persist/SQLCreator.java
@@ -0,0 +1,96 @@
+package frame.persist;
+
+import org.apache.log4j.Logger;
+
+import frame.config.Configer;
+import frame.data.DataBaseType;
+import frame.expression.Expression;
+import frame.expression.VariantSegment;
+import frame.util.Util;
+
+public class SQLCreator extends Expression {
+	
+	protected static Logger logger;
+
+	
+	static {
+		logger = Logger.getLogger(SQLCreator.class);
+	}
+	
+	public SQLCreator(String sql) throws Exception {
+		super(sql, 8);
+	}
+
+	@Override
+	public void addVariant(String name) throws Exception {
+		if (Util.isEmptyStr(name)) {
+			return;
+		}
+		
+		if (variantList.contains(name)) {
+			VariantSegment segment = variantList.get(name);
+			segments.add(segment);
+		}
+		else {
+			SQLVariant segment = new SQLVariant(name);
+			segments.add(segment);
+			variantList.add(name, segment);
+		}	
+	}
+
+	public static String deletePageLimit(String sql) {
+		DataBaseType dbType = Configer.getDataBaseType();
+		
+		if (DataBaseType.MySQL == dbType) {
+			return deleteMySQLPageLimit(sql);
+		}
+		else if (DataBaseType.Oracle == dbType) {
+			return deleteOraclePageLimit(sql);
+		}
+		else if (DataBaseType.SQLServer == dbType) {
+			return deleteSQLServerPageLimit(sql);
+		}
+
+		return null;
+	}
+
+	private static String deleteMySQLPageLimit(String sql) {
+		int pos_beginno = sql.indexOf("@{beginno}");
+		
+		while (pos_beginno > 0) {
+			int pos_pagesize = sql.indexOf("@{pagesize}", pos_beginno + 1);
+			int pos_limit = sql.lastIndexOf("limit ", pos_beginno);
+			
+			if (pos_pagesize > 0 && pos_limit > 0) {
+				sql = sql.substring(0, pos_limit) + sql.substring(pos_pagesize + "@{pagesize}".length());
+			}
+			
+			pos_beginno = sql.indexOf("@{beginno}", pos_beginno + 1);
+		}
+
+		return sql;
+	}
+
+	private static String deleteOraclePageLimit(String sql) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	private static String deleteSQLServerPageLimit(String sql) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	public static void main(String[] args) {
+		String sql = "select agreement.*, dealer.code, dealer.name,"
+				   + "(select count(1) from agreementArea where agreementArea.parentid = agreement.id) as areaCount,"
+				   + "(select count(1) from agreementProduct where agreementProduct.parentid = agreement.id) as productCount"
+				   + "from agreement"
+				   + "left join dealer on agreement.customerid = dealer.id"
+				   + "where @{filter}"
+				   + "limit @{beginno}, @{pagesize}";
+		
+		sql = deleteMySQLPageLimit(sql);
+		System.out.println(sql);
+	}
+}
diff --git a/src/frame/persist/SQLRunner.java b/src/frame/persist/SQLRunner.java
new file mode 100644
index 0000000..12d7ff9
--- /dev/null
+++ b/src/frame/persist/SQLRunner.java
@@ -0,0 +1,785 @@
+package frame.persist;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import frame.data.DataType;
+import frame.data.Entity;
+import frame.data.EntitySet;
+import frame.persist.IMetaDataLoader;
+import frame.persist.loader.EntityLoader;
+import frame.persist.loader.EntitySetLoader;
+import frame.persist.loader.ListLoader;
+import frame.persist.loader.ObjectLoader;
+import frame.persist.loader.PrimaryKeyLoader;
+import frame.persist.loader.ValueLoader;
+import frame.util.Util;
+
+
+public class SQLRunner {
+	
+	protected static Logger logger;
+	protected static ThreadLocal<Connection> activeConn;
+	private static Set<String> tableSet;
+
+	static {
+		logger = Logger.getLogger(SQLRunner.class);
+		tableSet = new HashSet<String>();
+		activeConn = new ThreadLocal<Connection>();
+	}
+	
+	public static synchronized void beginTrans() throws SQLException {
+		Connection conn = activeConn.get();
+		
+		if (conn == null) {
+			conn = ConnectionManager.createConnection();
+			conn.setAutoCommit(false);
+			activeConn.set(conn);
+		}
+	}
+	
+	public static void commit() throws Exception {
+		Connection conn = activeConn.get();
+		
+		if (conn == null) {
+			throw new Exception("empty conn, can not commit!");
+		}
+		
+		try {
+			conn.commit();
+		}
+		finally {
+			try {
+				conn.close();
+			}
+			catch (Exception e) {
+			}
+			activeConn.remove();	
+		}
+	}
+	
+	public static void rollback() throws Exception {
+		Connection conn = activeConn.get();
+		
+		if (conn == null) {
+			throw new Exception("empty conn, can not commit!");
+		}
+		
+		try {
+			conn.rollback();
+		}
+		finally {
+			try {
+				conn.close();
+			}
+			catch (Exception e) {
+			}
+			activeConn.remove();	
+		}		
+	}
+	
+	public static int execSQL(String sql) throws Exception {
+		NamedSQL namedSQL = new NamedSQL("temp", sql);
+		return execSQL(null, namedSQL);
+	}
+	
+	public static int execSQL(NamedSQL sql) throws Exception {
+		return execSQL(null, sql);
+	}
+	
+	public static int execSQL(Connection conn, NamedSQL sql) throws Exception {
+		 return execSQL(conn, sql.getSQLString());
+	}
+	
+	public static int execSQL(Connection conn, String sql) throws Exception {
+		Statement stmt = null;
+		int result = 0;
+		
+		if (conn == null) {
+			conn = activeConn.get();
+		}
+		boolean closeFlag = conn == null;
+
+		try {
+			if (conn == null) {
+				conn = ConnectionManager.createConnection();
+			}
+			
+			if (conn != null) {
+				logger.debug(sql);
+				stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+				
+				result = stmt.executeUpdate(sql);
+			}
+		} 
+		catch (SQLException e) {
+			onError(sql, e);
+			throw e;
+		}
+		finally {
+			try {
+				if (stmt != null) {
+					stmt.close();
+				}
+			} catch (SQLException e) {
+			} finally {
+				if (closeFlag && conn != null) {
+					conn.close();
+				}
+			}
+		}
+		return result;
+	}
+	
+	public static void getData(NamedSQL namedSQL, ILoadable loadable, Object ...args) throws Exception {
+		getData(null, namedSQL, loadable, args);
+	}
+	
+	public static void getData(NamedSQL namedSQL, IStepLoadable loadable, Object ...args) throws Exception {
+		getData(null, namedSQL, loadable, args);
+	}
+	
+	public static void getData(Connection conn, NamedSQL namedSQL, ILoadable loadable, Object ...args) throws Exception {
+		ResultSet rslt = null;
+		Statement stmt = null;
+
+		if (conn == null) {
+			conn = activeConn.get();
+		}
+		boolean closeFlag = conn == null;
+		String sql = namedSQL.getSQL();
+		
+		if (sql != null) {
+			sql.trim();
+			
+			if (!"".equals(sql)) {
+				try {
+					if (conn == null) {
+						conn = ConnectionManager.createConnection();
+					}
+
+					if (conn != null) {
+						logger.debug(sql);
+						stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+						rslt = stmt.executeQuery(sql);
+						
+						loadable.load(rslt, args);
+					}
+					else{
+						throw new SQLException("can not get coinnection");
+					}
+				} 
+				catch (SQLException e) {
+					logger.error("getDataFromDB error:" + e.getMessage());
+					throw e;
+				} 
+				finally {
+					try {
+						if (rslt != null) {
+							rslt.close();
+						}
+					} catch (SQLException e) {
+					}
+					finally {
+						try {
+							if (stmt != null) {
+								stmt.close();
+							}
+						} catch (SQLException e) {
+						}
+						finally {
+							if (closeFlag && conn != null) {
+								conn.close();
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public static void getData(Connection conn, NamedSQL namedSQL, IStepLoadable loadable, Object ...args) throws Exception {
+		ResultSet rslt = null;
+		PreparedStatement stmt = null;
+
+		if (conn == null) {
+			conn = activeConn.get();
+		}
+		boolean closeFlag = conn == null;
+		String sql = namedSQL.getSQLString();
+		
+		if(!sql.contains("limit")) {
+			sql += " limit ?, ?";
+		}
+		
+		try {
+			if (conn == null) {
+				conn = ConnectionManager.createConnection();
+			}
+
+			if (conn != null) {
+				while (loadable.hasNextForLoad()) {
+					stmt = conn.prepareStatement(sql);
+					loadable.setLoadParameters(stmt);
+					
+					try {
+						try {
+							rslt = stmt.executeQuery();
+							loadable.load(rslt, args);
+						}
+						finally {
+							if (rslt != null) {
+								rslt.close();
+							}
+						}						
+					}
+					finally {
+						if (stmt != null) {
+							stmt.close();
+						}
+					}
+				}
+			}
+			else{
+				throw new SQLException("can not get coinnection");
+			}
+		} 
+		catch (SQLException e) {
+			logger.debug(sql);
+			logger.error("getDataFromDB error:" + e.getMessage());
+			throw e;
+		} 
+		finally {
+			if (closeFlag && conn != null) {
+				conn.close();
+			}
+		}
+	}
+	
+	public static void saveData(NamedSQL namedSQL1, NamedSQL namedSQL2, IDoubleSavable savable, Object ...args) throws Exception {
+		saveData(null, namedSQL1, namedSQL2, savable, args);
+	}
+	
+	public static void saveData(NamedSQL namedSQL, ISavable savable, Object ...args) throws Exception {
+		saveData(null, namedSQL, savable, args);
+	}
+	
+	public static void saveData(Connection conn, NamedSQL namedSQL, ISavable savable, Object ...args) throws Exception {
+		ResultSet rslt = null;
+		PreparedStatement stmt = null;
+
+		String sql = namedSQL.getSQLString();
+		
+		if (sql != null) {
+			sql = sql.trim();
+			
+			if (conn == null) {
+				conn = activeConn.get();
+			}
+			boolean closeFlag = conn == null;
+			
+			if (!"".equals(sql)) {
+				try {
+					if (conn == null) {
+						conn = ConnectionManager.createConnection();
+					}
+					
+					if (conn != null) {
+						logger.debug(sql);
+						stmt = conn.prepareStatement(sql);
+						savable.save(stmt, args);
+					}
+					else{
+						throw new SQLException("can not get coinnection");
+					}
+				} 
+				catch (SQLException e) {
+					logger.error("getDataFromDB error:" + e.getMessage());
+					throw e;
+				} finally {
+					try {
+						if (rslt != null) {
+							rslt.close();
+						}
+					} catch (SQLException e) {
+					}
+					finally {
+						try {
+							if (stmt != null) {
+								stmt.close();
+							}
+						} catch (SQLException e) {
+						}
+						finally {
+							if (closeFlag && conn != null) {
+								conn.close();
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public static void saveData(Connection conn, NamedSQL namedSQL1, NamedSQL namedSQL2, IDoubleSavable savable, Object ...args) throws Exception {
+		PreparedStatement stmt1 = null, stmt2 = null;
+
+		String sql1 = namedSQL1.getSQLString();
+		String sql2 = namedSQL2.getSQLString();
+		
+		if (!Util.isEmptyStr(sql1) && !Util.isEmptyStr(sql2)) {
+			if (conn == null) {
+				conn = activeConn.get();
+			}
+			boolean closeFlag = conn == null;
+			
+			try {
+				if (conn == null) {
+					conn = ConnectionManager.createConnection();
+				}
+					
+				if (conn != null) {
+					logger.debug(sql1);
+					logger.debug(sql2);
+					
+					stmt1 = conn.prepareStatement(sql1);
+					stmt2 = conn.prepareStatement(sql2);
+					
+					savable.save(stmt1, stmt2, args);
+				}
+				else{
+					throw new SQLException("can not get coinnection");
+				}
+			} 
+			catch (SQLException e) {
+				logger.error("getDataFromDB error:" + e.getMessage());
+				throw e;
+			} finally {
+				try {
+					if (stmt1 != null) {
+						stmt1.close();
+					}
+				} catch (SQLException e) {
+				}
+				finally {
+					try {
+						if (stmt2 != null) {
+							stmt2.close();
+						}
+					} catch (SQLException e) {
+					}
+					finally {
+						if (closeFlag && conn != null) {
+							conn.close();
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	public static void saveData(NamedSQL namedSQL, IStepSavable stepSavable, Object ...args) throws Exception {
+		saveData(null, namedSQL, stepSavable, args);
+	}
+	
+	public static void saveData(Connection conn, NamedSQL namedSQL, IStepSavable stepSavable, Object ...args) throws Exception {
+		PreparedStatement stmt = null;
+
+		String sql = namedSQL.getSQLString();
+		
+		if (conn == null) {
+			conn = activeConn.get();
+		}
+		boolean closeFlag = conn == null;
+		
+		if (sql != null) {
+			sql.trim();
+			
+			if (!"".equals(sql)) {
+				try {
+					if (conn == null) {
+						conn = ConnectionManager.createConnection();
+					}
+					
+					if (conn != null) {
+						while (stepSavable.hasNextForSave()) {
+							stmt = conn.prepareStatement(sql);
+							
+							try {
+								stepSavable.save(stmt, args);
+							}
+							finally {
+								if (stmt != null) {
+									stmt.close();
+								}
+							}
+						}
+					}
+					else{
+						throw new SQLException("can not get coinnection");
+					}
+				} 
+				catch (SQLException e) {
+					logger.debug(sql);
+					logger.error("getDataFromDB error:" + e.getMessage());
+					throw e;
+				} 
+				finally {
+					if (closeFlag && conn != null) {
+						conn.close();
+					}
+				}
+			}
+		}
+	}
+
+	public static void getEntitySet(NamedSQL namedSQL, EntitySet entitySet) throws Exception {
+		getEntitySet(null, namedSQL, entitySet);
+	}
+	
+	public static EntitySet getEntitySet(NamedSQL namedSQL) throws Exception {
+		return getEntitySet(null, namedSQL);
+	}
+	
+	public static EntitySet getEntitySet(Connection conn, NamedSQL namedSQL) throws Exception {
+		EntitySet result = null;
+		
+		EntitySetLoader entitySetLoader = new EntitySetLoader(namedSQL.getName());
+		getData(conn, namedSQL, entitySetLoader);
+		result = entitySetLoader.getDataSet();
+		
+		return result;
+	}
+	
+	public static void getEntitySet(Connection conn, NamedSQL namedSQL, EntitySet entitySet) throws Exception {
+		EntitySetLoader entitySetLoader = new EntitySetLoader(entitySet);
+		getData(conn, namedSQL, entitySetLoader);
+	}
+	
+	public static <T> List<T> getList(NamedSQL namedSQL, Class<T> clazz) throws Exception {
+		return getList(null, namedSQL, clazz);
+	}
+	
+	public static <T> List<T> getList(Connection conn, NamedSQL namedSQL, Class<T> clazz) throws Exception {
+		List<T> result = null;
+		
+		ListLoader<T> listLoader = new ListLoader<T>(namedSQL.getName(), clazz);
+		getData(conn, namedSQL, listLoader);
+		result = listLoader.getList();
+		
+		return result;
+	}	
+	
+	public static void getEntity(NamedSQL namedSQL, Entity entity) throws Exception {
+		getEntity(null, namedSQL, entity);
+	}
+
+	public static Entity getEntity(NamedSQL namedSQL) throws Exception {
+		return getEntity(null, namedSQL);
+	}
+	
+	public static Entity getEntity(Connection conn, NamedSQL namedSQL) throws Exception {
+		Entity result = null;
+		
+		EntityLoader entityLoader = new EntityLoader(namedSQL.getName());
+		getData(conn, namedSQL, entityLoader);
+		result = entityLoader.getEntity();
+		
+		return result;
+	}
+	
+	public static void getEntity(Connection conn, NamedSQL namedSQL, Entity entity) throws Exception {
+		EntityLoader entityLoader = new EntityLoader(entity);
+		getData(conn, namedSQL, entityLoader);
+	}
+	
+	public static Object getObject(NamedSQL namedSQL, Class<?> clazz) throws Exception {
+		return getObject(null, namedSQL, clazz);
+	}
+
+	public static Object getObject(Connection conn, NamedSQL namedSQL, Class<?> clazz) throws Exception {
+		Object result = null;
+		
+		ObjectLoader objectLoader = new ObjectLoader(namedSQL.getName(), clazz);
+		getData(conn, namedSQL, objectLoader);
+		result = objectLoader.getObject();
+		
+		return result;
+	}
+	
+	public static String getString(NamedSQL namedSQL) throws Exception {
+		return getString(null, namedSQL, 1);
+	}
+	
+	public static String getString(Connection conn, NamedSQL namedSQL, int idx) throws Exception {
+		String result = null;
+		
+		ValueLoader valueLoader = new ValueLoader();
+		getData(conn, namedSQL, valueLoader);
+		result = valueLoader.getString();
+		
+		return result;
+	}
+	
+	public static int getInteger(NamedSQL namedSQL) throws Exception {
+		return getInteger(null, namedSQL);
+	}
+	
+	public static int getInteger(Connection conn, NamedSQL namedSQL) throws Exception {
+		int result = 0;
+		
+		ValueLoader valueLoader = new ValueLoader();
+		getData(conn, namedSQL, valueLoader);
+		result = valueLoader.getInt();
+		
+		return result;
+	}
+	
+	public static BigDecimal getBigDecimal(NamedSQL namedSQL) throws Exception {
+		return getBigDecimal(null, namedSQL);
+	}
+	
+	public static BigDecimal getBigDecimal(Connection conn, NamedSQL namedSQL) throws Exception {
+		BigDecimal result = null;
+		
+		ValueLoader valueLoader = new ValueLoader();
+		getData(conn, namedSQL, valueLoader);
+		result = valueLoader.getBigDecimal();
+		
+		return result;
+	}
+	
+	public static Date getDate(NamedSQL namedSQL) throws Exception {
+		return getDate(null, namedSQL);
+	}
+
+	public static Date getDate(Connection conn, NamedSQL namedSQL) throws Exception {
+		Date result = null;
+		
+		ValueLoader valueLoader = new ValueLoader();
+		getData(conn, namedSQL, valueLoader);
+		result = valueLoader.getDate();
+		
+		return result;
+	}
+	
+	public static Result getResult(NamedSQL namedSQL) throws Exception {
+		return getResult(null, namedSQL);
+	}
+	
+	public static Result getResult(Connection conn, NamedSQL namedSQL) throws Exception {
+		Result result = new Result();
+		DataType returnType = namedSQL.getReturnType();
+		
+		if (DataType.EntitySet == returnType) {
+			EntitySet value = getEntitySet(conn, namedSQL);
+			result.setValue(value);
+		}
+		else if (DataType.Entity == returnType) {
+			Entity value = getEntity(conn, namedSQL);
+			result.setValue(value);
+		}
+		else if (DataType.Int == returnType) {
+			int value = getInteger(conn, namedSQL);
+			result.setValue(value);
+		}
+		else if (DataType.String == returnType) {
+			String value = getString(conn, namedSQL, 1);
+			result.setValue(value);
+		}
+		else if (DataType.Decimal == returnType) {
+			BigDecimal value = getBigDecimal(conn, namedSQL);
+			result.setValue(value);
+		}
+		else if (DataType.Date == returnType) {
+			Date value = getDate(conn, namedSQL);
+			result.setValue(value);
+		}		
+		else {
+			int value = execSQL(conn, namedSQL);
+			result.setValue(value);
+		}
+		
+		return result;		
+	}
+
+	public static void getTableMetaData(IMetaDataLoader loader) throws SQLException {
+		getTableMetaData(null, loader);
+	}
+	
+	public static void getTableMetaData(Connection conn, IMetaDataLoader loader) throws SQLException {
+		String sql = null;
+		Statement stmt = null;
+		ResultSet rslt = null;
+		
+		if (conn == null) {
+			conn = activeConn.get();
+		}
+		boolean closeFlag = conn == null;
+		
+		try {
+			if (conn == null) {
+				conn = ConnectionManager.createConnection();
+			}
+
+			stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+			
+			sql = "select * from " + loader.getTableName() + " where 1 <> 1";
+			logger.debug(sql);
+			
+			rslt = stmt.executeQuery(sql);
+			ResultSetMetaData result = rslt.getMetaData();
+			loader.load(result);
+		} 
+		catch (Exception e) {
+			onError(sql, e);
+		} 
+		finally {
+			try {
+				if (rslt != null) {
+					rslt.close();					
+				}
+			} 
+			catch (SQLException e) {
+			} 
+			finally {
+				try {
+					if (stmt != null) {
+						stmt.close();						
+					}
+				} 
+				catch (SQLException e) {
+				} 
+				finally {
+					if (closeFlag && conn != null) {
+						conn.close();
+					}
+				}
+			}
+		}
+	}
+	
+	public static boolean isTableExists(String tableName) throws Exception {
+		if (tableName == null) {
+			return false;
+		}
+		
+		if (tableSet.contains(tableName.toLowerCase())) {
+			return true;
+		}
+		
+		boolean result = isTableExists(null, tableName);
+		
+		if (result) {
+			tableSet.add(tableName.toLowerCase());
+		}
+		
+		return result;
+	}
+	
+	public static boolean isTableExists(Connection conn, String tableName) throws Exception {
+		String sql = null;
+		Statement stmt = null;
+		ResultSet rslt = null;
+		
+		if (conn == null) {
+			conn = activeConn.get();
+		}
+		boolean closeFlag = conn == null;
+		
+		try {
+			if (conn == null) {
+				conn = ConnectionManager.createConnection();
+			}
+
+			stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+			sql = "select 1 from user_tables where table_name ='" + tableName.toUpperCase() + "'";
+			rslt = stmt.executeQuery(sql);
+			
+			if (rslt.next()) {
+				return true;
+			}
+			
+			return false;
+		} 
+		catch (Exception e) {
+			onError(sql, e);
+			throw e;
+		} 
+		finally {
+			try {
+				if (rslt != null) {
+					rslt.close();					
+				}
+			} 
+			catch (SQLException e) {
+			} 
+			finally {
+				try {
+					if (stmt != null) {
+						stmt.close();						
+					}
+				} 
+				catch (SQLException e) {
+				} 
+				finally {
+					if (closeFlag && conn != null) {
+						conn.close();
+					}
+				}
+			}
+		}
+	}
+	
+	protected static void onError(String sql, Exception e) {
+		logger.error("executor exec error: " + e.getMessage());
+	}
+
+	public static void getPrimaryKeyFields(ILoadable loadable) throws Exception {
+		NamedSQL namedSQL = getPrimaryKeyFieldSQL(null);
+		getData(namedSQL, loadable);
+	}
+	
+	public static String getPrimaryKeyField(Connection conn, String tableName) throws Exception {
+		NamedSQL namedSQL = getPrimaryKeyFieldSQL(tableName);
+		PrimaryKeyLoader loader  = new PrimaryKeyLoader();
+		
+		getData(conn, namedSQL, loader);
+		
+		return loader.getPrimaryKeyField();
+	}
+	
+	private static NamedSQL getPrimaryKeyFieldSQL(String tableName) throws Exception {
+		StringBuilder result = new StringBuilder();
+		result.append("SELECT columns.owner AS table_schem, columns.table_name, columns.column_name");
+		result.append(" FROM all_cons_columns columns, all_constraints constraints");
+		result.append(" WHERE constraints.constraint_type = 'P'");
+		
+		result.append("   AND constraints.constraint_name = columns.constraint_name");
+		result.append("   AND constraints.table_name = columns.table_name");
+		result.append("   AND constraints.owner = columns.owner");
+		
+		if (tableName != null) {
+			tableName = tableName.toUpperCase();
+			result.append("   AND columns.table_name = '" + tableName + "'");
+		}
+		
+		result.append(" ORDER BY table_name");
+		
+		NamedSQL namedSQL = new NamedSQL("getPrimaryKey", result.toString());
+		
+		return namedSQL;
+	}
+
+}
diff --git a/src/frame/persist/SQLVariant.java b/src/frame/persist/SQLVariant.java
new file mode 100644
index 0000000..48567ec
--- /dev/null
+++ b/src/frame/persist/SQLVariant.java
@@ -0,0 +1,26 @@
+package frame.persist;
+
+import frame.expression.VariantSegment;
+
+
+public class SQLVariant extends VariantSegment {
+
+	public SQLVariant(String name) {
+		super(name);
+	}
+
+	@Override
+	public SQLVariant newInstance() {
+		SQLVariant result = new SQLVariant(name);
+		
+		if (NamedSQL.Param_Filter.equalsIgnoreCase(name)) {
+			result.value = " 1 = 1 ";
+		}
+		else if (NamedSQL.Param_OrderBy.equalsIgnoreCase(name)) {
+			result.value = "";
+		}
+		
+		return result;
+	}
+	
+}
diff --git a/src/frame/persist/loader/DataLoader.java b/src/frame/persist/loader/DataLoader.java
new file mode 100644
index 0000000..a7ab39d
--- /dev/null
+++ b/src/frame/persist/loader/DataLoader.java
@@ -0,0 +1,44 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import frame.data.meta.EntityMeta;
+import frame.persist.ILoadable;
+
+
+public abstract class DataLoader implements ILoadable {
+
+	protected String tableName;
+	protected EntityMeta entityMeta;
+	
+	
+	protected DataLoader() {
+		
+	}
+	
+	public DataLoader(String tableName) {
+		this.tableName = tableName;
+	}
+
+	public void load(ResultSet rslt, Object... args) throws Exception {
+		ResultSetMetaData metaData = rslt.getMetaData();
+		loadTableMeta(metaData);
+		
+		loadData(rslt);
+	}
+
+	private void loadTableMeta(ResultSetMetaData metaData) throws SQLException {
+		if (entityMeta == null) {
+			ResultMetaFieldReader fieldReader = new ResultMetaFieldReader(metaData);
+			entityMeta = new EntityMeta(tableName, fieldReader);
+		}
+	}
+
+	protected abstract void loadData(ResultSet rslt) throws Exception;
+
+	public void setTableMeta(EntityMeta entityMeta) {
+		this.entityMeta = entityMeta;
+	}
+}
diff --git a/src/frame/persist/loader/EntityLoader.java b/src/frame/persist/loader/EntityLoader.java
new file mode 100644
index 0000000..0eb0131
--- /dev/null
+++ b/src/frame/persist/loader/EntityLoader.java
@@ -0,0 +1,41 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+
+import frame.data.Entity;
+
+public class EntityLoader extends DataLoader {
+
+	private Entity entity;
+	
+	public EntityLoader(String tableName) {
+		super(tableName);
+	}
+	
+	public EntityLoader(Entity entity) {
+		this.entity = entity;
+		
+		this.tableName = entity.getDataName();
+		this.entityMeta = entity.getEntityMeta();
+	}
+
+	@Override
+	protected void loadData(ResultSet rslt) throws Exception {
+		if (rslt.next()) {
+			entity = new Entity(entityMeta);
+			int cnt = entity.getFieldCount();
+			
+			Object obj;
+			
+			for (int i = 0; i < cnt; i++) {
+				obj = rslt.getObject(i + 1);
+				entity.set(i, obj);
+			}
+		}		
+	}
+
+	public Entity getEntity() {
+		return entity;
+	}
+
+}
diff --git a/src/frame/persist/loader/EntitySetLoader.java b/src/frame/persist/loader/EntitySetLoader.java
new file mode 100644
index 0000000..e67abbe
--- /dev/null
+++ b/src/frame/persist/loader/EntitySetLoader.java
@@ -0,0 +1,44 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+
+import frame.data.Entity;
+import frame.data.EntitySet;
+
+public class EntitySetLoader extends DataLoader {
+
+	private EntitySet entitySet;
+	
+	public EntitySetLoader(String tableName) {
+		super(tableName);
+	}
+
+	public EntitySetLoader(EntitySet entitySet) {
+		this.entitySet = entitySet;
+		
+		this.tableName = entitySet.getDataName();
+		this.entityMeta = entitySet.getEntityMeta();
+	}
+
+	protected void loadData(ResultSet rslt) throws Exception {
+		entitySet = new EntitySet(entityMeta);
+		int cnt = entitySet.getFieldCount();
+		
+		Entity entity;
+		Object obj;
+		
+		while (rslt.next()) {
+			entity = entitySet.append();
+			
+			for (int i = 0; i < cnt; i++) {
+				obj = rslt.getObject(i + 1);
+				entity.set(i, obj);
+			}
+		}
+	}
+
+	public EntitySet getDataSet() {
+		return entitySet;
+	}
+
+}
diff --git a/src/frame/persist/loader/ListLoader.java b/src/frame/persist/loader/ListLoader.java
new file mode 100644
index 0000000..9df43a9
--- /dev/null
+++ b/src/frame/persist/loader/ListLoader.java
@@ -0,0 +1,56 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+
+import frame.data.meta.Field;
+import frame.data.reader.EntityReaderContainer;
+import frame.data.reader.ObjectReader;
+
+public class ListLoader<T> extends DataLoader {
+
+	protected static EntityReaderContainer objectReaderContainer;
+	private Class<T> clazz;
+	private ObjectReader objectReader;
+	private List<T> list;
+	
+	static {
+		objectReaderContainer = EntityReaderContainer.getInstance();
+	}
+
+	public ListLoader(String tableName, Class<T> clazz) throws Exception {
+		super(tableName);
+		
+		this.clazz = clazz;
+		objectReader = objectReaderContainer.getObjectReader(clazz);
+	}
+	
+	@Override 
+	protected void loadData(ResultSet rslt) throws Exception {
+		list = new ArrayList<T>();
+		
+		List<Field> fields = entityMeta.getFields();
+		T object; int size = fields.size(); String name;
+		
+		while (rslt.next()) {
+			object = clazz.newInstance();
+			list.add(object);
+			
+			for (int i = 1; i <= size; i++) {
+				Field field = fields.get(i);
+				name = field.getName();
+				
+				if (objectReader.containsProperty(name)) {
+					Object value = rslt.getObject(i);
+					objectReader.setData(name, value, object);
+				}
+			}
+		}
+	}
+
+	public List<T> getList() {
+		return list;
+	}
+
+}
diff --git a/src/frame/persist/loader/ObjectLoader.java b/src/frame/persist/loader/ObjectLoader.java
new file mode 100644
index 0000000..2d4e5a9
--- /dev/null
+++ b/src/frame/persist/loader/ObjectLoader.java
@@ -0,0 +1,58 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+import java.util.List;
+
+import frame.data.meta.Field;
+import frame.data.reader.EntityReaderContainer;
+import frame.data.reader.ObjectReader;
+
+public class ObjectLoader extends DataLoader {
+
+	protected static EntityReaderContainer objectReaderContainer;
+	private Class<?> clazz;
+	private ObjectReader objectReader;
+	private Object object;
+	
+	static {
+		objectReaderContainer = EntityReaderContainer.getInstance();
+	}
+
+	public ObjectLoader(String tableName, Class<?> clazz) throws Exception {
+		super(tableName);
+		
+		this.clazz = clazz;
+		objectReader = objectReaderContainer.getObjectReader(clazz);
+	}
+	
+	@Override
+	protected void loadData(ResultSet rslt) throws Exception {
+		if (rslt.next()) {
+			if (object == null) {
+				object = clazz.newInstance();
+			}
+			
+			List<Field> fields = entityMeta.getFields();
+			int size = fields.size(); String name;
+			
+			for (int i = 0; i < size; i++) {
+				Field field = fields.get(i);
+				name = field.getName();
+				
+				if (objectReader.containsProperty(name)) {
+					Object value = rslt.getObject(i + 1);
+					objectReader.setData(name, value, object);
+				}
+			}
+		}
+	}
+	
+	public Object getObject() {
+		return object;
+	}
+
+	public void setObject(Object object) {
+		this.object = object;
+	}
+	
+}
diff --git a/src/frame/persist/loader/PrimaryKeyLoader.java b/src/frame/persist/loader/PrimaryKeyLoader.java
new file mode 100644
index 0000000..490353d
--- /dev/null
+++ b/src/frame/persist/loader/PrimaryKeyLoader.java
@@ -0,0 +1,72 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import frame.config.Configer;
+import frame.persist.ILoadable;
+
+
+public class PrimaryKeyLoader implements ILoadable {
+
+	private Map<String, String> items;
+	private String schema;
+	private String keyField;
+	private String table;
+	
+	
+	public PrimaryKeyLoader() {
+		items = new HashMap<String, String>();
+	}
+	
+	public void load(ResultSet rslt, Object ...arg) throws Exception {
+		String table_schem;
+		String fieldName;
+		
+		while (rslt.next()) {
+			table_schem = rslt.getString(1);
+			fieldName = rslt.getString(3);
+			keyField = fieldName;
+			
+			append(table_schem, fieldName);
+		}
+	}
+
+	private void append(String tableSchem, String fieldName) {
+		items.put(tableSchem.toLowerCase(), fieldName);
+	}
+
+	public String getPrimaryKeyField() throws Exception {
+		int size = items.size();
+		
+		if (size == 0) {
+			return null;
+		}
+		
+		if (size == 1) {
+			return keyField;
+		}
+		
+		Set<String> keys = items.keySet();
+		
+		if (schema == null) {
+			schema = Configer.getDataBase_Schema();
+		}
+		
+		for (String key: keys) {
+			if (key.equalsIgnoreCase(schema)) {
+				keyField = items.get(key);
+				return keyField;
+			}
+		}
+		
+		throw new Exception("can not get primary key field: more than one schema has the table [" + table + "], you should privade schema");
+	}
+
+	public void setSchema(String schema) {
+		this.schema = schema;
+	}
+
+}
diff --git a/src/frame/persist/loader/ResultMetaFieldReader.java b/src/frame/persist/loader/ResultMetaFieldReader.java
new file mode 100644
index 0000000..66e3b7d
--- /dev/null
+++ b/src/frame/persist/loader/ResultMetaFieldReader.java
@@ -0,0 +1,50 @@
+package frame.persist.loader;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import frame.data.meta.IFieldReader;
+
+public class ResultMetaFieldReader implements IFieldReader {
+	
+	private ResultSetMetaData resultMeta;
+	private int pos;
+	
+	
+	public ResultMetaFieldReader(ResultSetMetaData resultMeta) {
+		this.resultMeta = resultMeta;
+		pos = 0;
+	}
+
+	public String getFieldName() throws SQLException {
+		return resultMeta.getColumnName(pos);
+	}
+
+	public int getFieldType() throws SQLException {
+		int value = resultMeta.getColumnType(pos);
+		return value;
+	}
+
+	public int getFieldLength() throws SQLException {
+		return resultMeta.getColumnDisplaySize(pos);
+	}
+
+	public int getNullable() throws SQLException {
+		return resultMeta.isNullable(pos);
+	}
+
+	public boolean next() throws SQLException {
+		if (pos < resultMeta.getColumnCount()) {
+			pos++;
+			return true;
+		}
+
+		return false;
+	}
+
+	@Override
+	public void first() {
+		pos = 0;
+	}
+
+}
diff --git a/src/frame/persist/loader/ResultSetFieldReader.java b/src/frame/persist/loader/ResultSetFieldReader.java
new file mode 100644
index 0000000..8be46cb
--- /dev/null
+++ b/src/frame/persist/loader/ResultSetFieldReader.java
@@ -0,0 +1,47 @@
+package frame.persist.loader;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import frame.data.meta.IFieldReader;
+
+public class ResultSetFieldReader implements IFieldReader {
+
+	private ResultSet resultSet;
+	
+	
+	public ResultSetFieldReader(ResultSet resultSet) {
+		this.resultSet = resultSet;
+	}
+
+	public boolean next() throws SQLException {
+		return resultSet.next();
+	}
+	
+	public String getFieldName() throws SQLException {
+		return resultSet.getString(4);
+	}
+	
+	public int getFieldType() throws SQLException {
+		int value = resultSet.getInt(5);
+		return value;
+	}
+
+	public int getFieldLength() throws SQLException {
+		return resultSet.getInt(7);
+	}
+
+	public int getNullable() throws SQLException {
+		return resultSet.getInt(11);
+	}
+
+	@Override
+	public void first() {
+		try {
+			resultSet.first();
+		}
+		catch (Exception e) {
+		}
+	}
+
+}
diff --git a/src/frame/persist/loader/ValueLoader.java b/src/frame/persist/loader/ValueLoader.java
new file mode 100644
index 0000000..69f5e81
--- /dev/null
+++ b/src/frame/persist/loader/ValueLoader.java
@@ -0,0 +1,46 @@
+package frame.persist.loader;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.util.Date;
+
+import frame.data.convert.Convertor;
+import frame.persist.ILoadable;
+
+
+public class ValueLoader implements ILoadable {
+
+	private Object object;
+	
+	public ValueLoader() {
+		
+	}
+
+	@Override
+	public void load(ResultSet rslt, Object... args) throws Exception {
+		if (rslt.next()) {
+			object = rslt.getObject(1);
+		}		
+	}
+	
+	public int getInt() throws Exception {
+		return Convertor.toInteger(object, -1);
+	}
+	
+	public String getString() throws Exception {
+		return Convertor.toString(object);
+	}
+
+	public BigDecimal getBigDecimal() throws Exception {
+		return Convertor.toBigDecimal(object);
+	}
+	
+	public Date getDate() throws Exception {
+		return Convertor.toDate(object);
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+}
diff --git a/src/frame/role/DepartmentRight.java b/src/frame/role/DepartmentRight.java
new file mode 100644
index 0000000..30615ad
--- /dev/null
+++ b/src/frame/role/DepartmentRight.java
@@ -0,0 +1,5 @@
+package frame.role;
+
+public class DepartmentRight {
+
+}
diff --git a/src/frame/role/OnlineAnymous.java b/src/frame/role/OnlineAnymous.java
new file mode 100644
index 0000000..eed7de8
--- /dev/null
+++ b/src/frame/role/OnlineAnymous.java
@@ -0,0 +1,26 @@
+package frame.role;
+
+public class OnlineAnymous extends OnlineUser {
+
+	private static OnlineAnymous instance;
+	
+	static {
+		instance = new OnlineAnymous();
+	}
+	
+	public static OnlineAnymous getInstance() {
+		return instance;
+	}
+	
+	public OnlineAnymous() {
+		super();
+		
+		id = "anymous";
+		name = "anymous";
+		emp_name = "娴嬭瘯鐢ㄦ埛";
+		orgid = "anymous";
+		orgCode = "anymous";
+		orgName = "anymous";
+	}
+
+}
diff --git a/src/frame/role/OnlineUser.java b/src/frame/role/OnlineUser.java
new file mode 100644
index 0000000..45989f0
--- /dev/null
+++ b/src/frame/role/OnlineUser.java
@@ -0,0 +1,270 @@
+package frame.role;
+
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import frame.persist.ILoadable;
+import frame.persist.loader.ObjectLoader;
+import frame.util.Util;
+
+
+public class OnlineUser implements ILoadable {
+
+	protected String id;
+	protected String name;
+	protected String password;
+	protected String rolecode;
+	protected String phone;
+	protected String type;
+	protected String emp_id;
+	protected String emp_name;
+	protected String emp_enName;
+	protected String emp_title;
+	protected String emp_enTitle;
+	protected String emp_department;
+	protected String emp_enDepartment;
+	protected String emp_position;
+	protected int activeYear;
+	protected int activeMonth;
+	protected String orgCode;
+	protected String orgName;
+	protected String orgEnName;
+	protected String orgid;
+	protected String defaultRowfilter;
+	protected boolean onlyOne;
+	protected Map<String, String> rowfilterMap;
+	protected FileLockManager fileLockManager;
+	protected Map<String, Object> dataMap;
+	
+	
+	public OnlineUser() {
+		rowfilterMap = new HashMap<String, String>();
+		fileLockManager = new FileLockManager();
+	}
+
+	public String getPhone() {
+		return phone;
+	}
+
+	public void setPhone(String phone) {
+		this.phone = phone;
+	}
+
+	public synchronized String getRowfilter(String data, String template) {
+		if (!Util.isEmptyStr(defaultRowfilter)) {
+			return defaultRowfilter;
+		}
+		
+		String rowfilter = rowfilterMap.get(data);
+		
+		if (rowfilter != null) {
+			return rowfilter;
+		}
+		
+		if (template == null) {
+			return null;
+		}
+		
+		rowfilter = template.replace("@{userid}", id);
+		rowfilter = rowfilter.replace("@{orgid}", orgid);
+		
+		rowfilterMap.put(data, rowfilter);
+		
+		return rowfilter;
+	}
+
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+
+	public boolean isEmpty() {
+		return Util.isEmptyStr(id);
+	}
+	
+	public String getId() {
+		return id;
+	}
+
+	public String getOrgName() {
+		return orgName;
+	}
+
+	@Override
+	public void load(ResultSet rslt, Object... args) throws Exception {
+		onlyOne = true;
+		
+		ObjectLoader loader = new ObjectLoader("usr", this.getClass());
+		loader.setObject(this);
+		loader.load(rslt, args);
+		
+		if (rslt.next()) {
+			onlyOne = false;
+		}
+	}
+
+	public String getOrgId() {
+		return orgid;
+	}
+	
+	public String getOrgCode() {
+		return orgCode;
+	}
+	
+	public String getRoleCode() {
+		return rolecode;
+	}
+
+	public boolean isOnlyOne() {
+		return onlyOne;
+	}
+	
+	public String getRolecode() {
+		return rolecode;
+	}
+	
+	public String getPassword() {
+		return password;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public void setRolecode(String rolecode) {
+		this.rolecode = rolecode;
+	}
+
+	public String getOrgid() {
+		return orgid;
+	}
+
+	public void setOrgid(String orgid) {
+		this.orgid = orgid;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public void setOrgCode(String orgCode) {
+		this.orgCode = orgCode;
+	}
+	
+	public String getOrgEnName() {
+		return orgEnName;
+	}
+
+	public void setOrgEnName(String orgEnName) {
+		this.orgEnName = orgEnName;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getEmp_id() {
+		return emp_id;
+	}
+
+	public void setEmp_id(String emp_id) {
+		this.emp_id = emp_id;
+	}
+
+	public String getEmp_name() {
+		return emp_name;
+	}
+
+	public void setEmp_name(String emp_name) {
+		this.emp_name = emp_name;
+	}
+
+	public String getEmp_enName() {
+		return emp_enName;
+	}
+
+	public void setEmp_enName(String emp_enName) {
+		this.emp_enName = emp_enName;
+	}
+
+	public String getEmp_title() {
+		return emp_title;
+	}
+
+	public void setEmp_title(String emp_title) {
+		this.emp_title = emp_title;
+	}
+
+	public String getEmp_enTitle() {
+		return emp_enTitle;
+	}
+
+	public void setEmp_enTitle(String emp_enTitle) {
+		this.emp_enTitle = emp_enTitle;
+	}
+
+	public String getEmp_department() {
+		return emp_department;
+	}
+
+	public void setEmp_department(String emp_department) {
+		this.emp_department = emp_department;
+	}
+
+	public String getEmp_enDepartment() {
+		return emp_enDepartment;
+	}
+
+	public void setEmp_enDepartment(String emp_enDepartment) {
+		this.emp_enDepartment = emp_enDepartment;
+	}
+
+	public String getEmp_position() {
+		return emp_position;
+	}
+
+	public void setEmp_position(String emp_position) {
+		this.emp_position = emp_position;
+	}
+
+	public int getActiveYear() {
+		return activeYear;
+	}
+
+	public int getActiveMonth() {
+		return activeMonth;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public FileProgressor getFileProgress(String code) {
+		return fileLockManager.getFileProgress(code);
+	}
+
+	public FileLock getFileLock(String name) {
+		return fileLockManager.getLock(name);
+	}
+
+	public Object getData(String name) {
+		return dataMap.get(name);
+	}
+	
+	public void setData(String name, Object data) {
+		dataMap.put(name, data);
+	}
+
+	public UserRight getUserRight() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
diff --git a/src/frame/role/OrgRight.java b/src/frame/role/OrgRight.java
new file mode 100644
index 0000000..178afcf
--- /dev/null
+++ b/src/frame/role/OrgRight.java
@@ -0,0 +1,5 @@
+package frame.role;
+
+public class OrgRight {
+
+}
diff --git a/src/frame/role/Role.java b/src/frame/role/Role.java
new file mode 100644
index 0000000..4bc51fd
--- /dev/null
+++ b/src/frame/role/Role.java
@@ -0,0 +1,78 @@
+package frame.role;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import frame.object.http.Path;
+import frame.util.Util;
+
+
+
+public class Role {
+
+	private String name;
+	private Set<String> dataSet;
+	private Set<String> includeResources;
+	private Set<String> endsWithResource;
+	private Set<String> cachedAuthorization;
+	
+	public Role(String name) {
+		this.name = name;
+		dataSet = new HashSet<String>();
+		includeResources = new HashSet<String>();
+		endsWithResource = new HashSet<String>();
+		cachedAuthorization = new HashSet<String>();
+	}
+	
+	public boolean containsData(String data) {
+		return dataSet.contains(data);
+	}
+
+	public boolean containsPath(Path path) {
+		String uri = path.getURI();
+		
+		if (cachedAuthorization.contains(uri)) {
+			return true;
+		}
+		
+		for (String include: includeResources) {
+			if (uri.contains(include)) {
+				return true;
+			}
+		}
+		
+		for (String endswidth: cachedAuthorization) {
+			if (uri.endsWith(endswidth)) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+
+	public void addResource(String resource) {
+		if (Util.isEmptyStr(resource)) {
+			return;
+		}
+		
+		resource = resource.trim().toLowerCase();
+		
+		if (resource.startsWith("/")) {
+			
+		}
+		
+		if (resource.endsWith("/*")) {
+			resource = resource.substring(0, resource.length() - "/*".length());
+			includeResources.add(resource);
+			return;
+		}
+		
+		endsWithResource.add(resource);
+	}
+
+	@Override
+	public String toString() {
+		return "Role [name=" + name + "]";
+	}
+	
+}
diff --git a/src/frame/role/Scenario.java b/src/frame/role/Scenario.java
new file mode 100644
index 0000000..424b082
--- /dev/null
+++ b/src/frame/role/Scenario.java
@@ -0,0 +1,42 @@
+package frame.role;
+
+import javax.sql.DataSource;
+
+public class Scenario {
+
+	private String code;
+	private DataSource dataSource;
+	private ActivePeriod activePeriod;
+	
+	
+	public Scenario(String code) {
+		this.code = code;
+		
+	}
+
+	public void setDataSource(DataSource dataSource) {
+		this.dataSource = dataSource; 
+	}
+
+	public void setActivePeriod(ActivePeriod activePeriod) {
+		this.activePeriod = activePeriod;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+
+	public DataSource getDataSource() {
+		return dataSource;
+	}
+
+	public ActivePeriod getActivePeriod() {
+		return activePeriod;
+	}
+
+	@Override
+	public String toString() {
+		return "datasource--" + code;
+	}
+
+}
diff --git a/src/frame/role/Statistics.java b/src/frame/role/Statistics.java
new file mode 100644
index 0000000..c6f39bd
--- /dev/null
+++ b/src/frame/role/Statistics.java
@@ -0,0 +1,52 @@
+package frame.role;
+
+public class Statistics implements Comparable<Statistics> {
+	
+	private String ip;
+	private Integer cnt;
+	private String date;
+
+	public Statistics(String ip, Integer cnt, String date) {
+		this.ip = ip;
+		this.cnt = cnt;
+		this.date = date;
+	}
+
+	public String getIp() {
+		return ip;
+	}
+
+	public void setIp(String ip) {
+		this.ip = ip;
+	}
+
+	public Integer getCnt() {
+		return cnt;
+	}
+
+	public void setCnt(Integer cnt) {
+		this.cnt = cnt;
+	}
+	
+	public String getDate() {
+		return date;
+	}
+
+	public void setDate(String date) {
+		this.date = date;
+	}
+
+	@Override
+	public int compareTo(Statistics o) {// 閫嗗簭
+		if (this.cnt > o.getCnt())
+			return -1;
+
+		if (this.cnt == o.getCnt())
+			return 0;
+
+		if (this.cnt < o.getCnt())
+			return 1;
+
+		return 0;
+	}
+}
diff --git a/src/frame/role/User.java b/src/frame/role/User.java
new file mode 100644
index 0000000..722e5a4
--- /dev/null
+++ b/src/frame/role/User.java
@@ -0,0 +1,235 @@
+package frame.role;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+import javax.servlet.http.HttpSession;
+
+import frame.config.Configer;
+import frame.data.Entity;
+import frame.data.EntitySet;
+import frame.object.http.HttpObject;
+import frame.object.http.Path;
+import frame.persist.DataCenter;
+import frame.persist.NamedSQL;
+import frame.persist.SQLRunner;
+import frame.util.Util;
+
+
+public class User extends HttpObject {
+
+	public static String Error_NotExist = "USER_NotExist";
+	public static String Error_EmptyOrgCode = "USER_EmptyOrgCode";
+	public static String Error_InvalidUser = "USER_InvalidUser";
+	public static String Error_InvalidVCode = "USER_InvalidVCode";
+	public static String Error_EmptyVCodeOrPassword = "USER_EmptyVCodeOrPass";
+	public static String Error_MultiUser = "USER_MultiUser";
+	
+	public static boolean isTest = false;
+	public static final String Code_UserName = "username";
+	public static String Code_User_Dealer = "user_dealer";
+	public static String Code_User_Manufacturer = "user_manufacturer";
+	public static String SuperVCode;
+	private static Random random;
+	
+	static {
+		random = new Random();
+		SuperVCode = Configer.getParam("SuperVCode");
+		isTest = !Util.stringToBoolean(Configer.getParam("SendSMS"));
+	}
+	
+	@Override
+	protected void doReceive(Path path) throws Exception {
+		if (Util.isEmptyStr(path.getOperator())) {
+			String operator = path.getOperator();
+			
+			if ("login".equalsIgnoreCase(operator)) {
+				login();
+			}
+			else if ("logout".equalsIgnoreCase(operator)) {
+				logout();
+			}
+			else if ("getvcade".equalsIgnoreCase(operator)) {
+				getVcode();
+			}			
+			else if ("changePassword".equalsIgnoreCase(operator)) {
+				changePassword();
+			}
+			else if ("getinfo".equalsIgnoreCase(operator)) {
+				getInfo();
+			}
+			else if ("getMenu".equalsIgnoreCase(operator)) {
+				getMenu();
+			}
+			else if ("getStatistics".equalsIgnoreCase(operator)) {
+				getStatistics();
+			}
+		}
+		else {
+			writer.ReplyError("bad data message path:" + path.getPathString());
+		}
+	}
+	
+	private void getVcode() throws Exception {
+		String phone = request.getParameter("phone");
+		
+		if (Util.isEmptyStr(phone)) {
+			resultPool.error("鐢佃瘽鍙风爜涓虹┖");
+			return;
+		}
+		
+		String vcode = "";
+		
+		for (int i = 0; i < 6; i++) {
+			int value = random.nextInt(9);
+			
+			if (value <= 0) {
+				value = 1;
+			}
+			
+			vcode = vcode + value;
+		}
+		
+		//TODO  sendsms
+		//SendResult sendResult = Sendsms.sendVCode(phone, vcode);
+		
+//		if (sendResult.isSuccess()) {
+//			HttpSession session = request.getSession(true);
+//			session.setAttribute("vcode", vcode);
+//			resultPool.success();			
+//		}
+//		else {
+//			resultPool.error(sendResult.getMsg());
+//		}
+	}
+
+	private void login() throws Exception {
+		HttpSession session = request.getSession(true);
+		
+		String orgCode = request.getParameter("org");
+		String phone = request.getParameter("phone");
+		String username = request.getParameter("username");
+		String password = request.getParameter("password");		
+		String vcode = request.getParameter("vcode");
+		
+		//1. 妫�鏌ョ敤鎴锋槸鍚﹀瓨鍦�
+		NamedSQL namedSQL = NamedSQL.getInstance("getClientUserByPhoneOrName");
+		namedSQL.setParam("phone", phone, "empty_phone");
+		namedSQL.setParam("username", username, "empty_username");
+		Entity entity = SQLRunner.getEntity(namedSQL);
+		
+		if (entity == null) {
+			resultPool.error(Error_NotExist, "user not exists");
+			return;
+		}
+		
+		//2.妫�鏌ユ槸鍚﹂渶瑕佸叕鍙哥爜 
+		boolean orgcheck = entity.getBoolean("orgcheck");
+		if (orgcheck && Util.isEmptyStr(orgCode)) {
+			resultPool.error(Error_EmptyOrgCode, "empty org code");
+			return;			
+		}
+		
+		//3.楠岃瘉鐮佹垨瀵嗙爜鏄惁姝g‘
+		if (!Util.isEmptyStr(vcode)) {
+			if (!vcode.equals(SuperVCode)) {
+				String sourceVcode = (String)session.getAttribute("vcode");
+				
+				if (!vcode.equals(sourceVcode)) {
+					resultPool.error(Error_InvalidVCode, "invalid vcode");
+					return;
+				}
+			}
+		}
+		else if (!Util.isEmptyStr(password)) {
+			if (!password.equals(entity.getString("password"))) {
+				resultPool.error(Error_InvalidUser, "invalid username or password");
+				return;
+			}
+		}
+		else {
+			resultPool.error(Error_EmptyVCodeOrPassword, "empty vcode or password");
+			return;
+		}
+		
+		//4銆佹鏌ョ數璇濆彿鐮併�佸叕鍙哥爜鏄惁姝g‘, 鑾峰彇鐢ㄦ埛鍜屽叕鍙镐俊鎭�
+		String orgFilter = Util.isEmptyStr(orgCode) ? "" : " and org.code = '" + orgCode + "'" ;
+		String userFilter = Util.isEmptyStr(phone) ? "usr.name = '" + username + "' and usr.password = '" + password + "'" : "usr.phone = '" + phone + "'";
+		
+		OnlineUser onlineUser = new OnlineUser();
+		
+		namedSQL = NamedSQL.getInstance("getUser");
+		namedSQL.setParam("userfilter", userFilter);
+		namedSQL.setParam("orgfilter", orgFilter);
+		SQLRunner.getData(namedSQL, onlineUser);
+
+		if (onlineUser.isEmpty()) {
+			resultPool.error(Error_InvalidUser, "invalid username or password");
+			return;
+		}
+		
+		if (!onlineUser.isOnlyOne()) {
+			resultPool.error(Error_MultiUser, "multi user, need orgCode");
+			return;
+		}
+			
+		session.setAttribute(OnlineUser.class.getSimpleName(), onlineUser);
+		resultPool.success();		
+	}
+
+	private void logout() throws Exception {
+		HttpSession session = request.getSession(true);
+		session.invalidate();
+			
+		resultPool.success();
+	}
+
+	private void changePassword() throws Exception {
+		String username = onlineUser.getName();
+		String password = request.getParameter("pass");
+		
+		if (Util.isEmptyStr(username)) {
+			resultPool.error("鐢ㄦ埛鍚嶄涪澶�");
+		}
+		else if (Util.isEmptyStr(password)) {
+			resultPool.error("瀵嗙爜涓㈠け");
+		}
+		else {
+			DataCenter.changePassword(username, password);
+			resultPool.success();
+		}
+	}
+	
+	private void getInfo() throws Exception {
+		resultPool.addValue("user", onlineUser);
+	}
+	
+	private void getMenu() throws Exception {
+		NamedSQL namedSQL = NamedSQL.getInstance("getUserMenu");
+		namedSQL.setParam("rolecode", onlineUser.getRolecode());
+		EntitySet entitySet = SQLRunner.getEntitySet(namedSQL);
+		
+		resultPool.addValue("dataSet", entitySet);
+	}
+	
+	@SuppressWarnings("unchecked")
+	private void getStatistics() {
+		List<Statistics> stacs = new ArrayList<Statistics>();
+		Statistics stac;
+
+		Map<String, Statistics> visitor = (Map<String, Statistics>) request.getServletContext().getAttribute("visitor");
+		Set<String> keySet = visitor.keySet();
+		for (String ip : keySet) {
+			stac = visitor.get(ip);
+			stacs.add(stac);
+		}
+		Collections.sort(stacs);
+
+		resultPool.addValue(stacs);
+	}
+
+}
diff --git a/src/frame/role/UserRight.java b/src/frame/role/UserRight.java
new file mode 100644
index 0000000..b61551c
--- /dev/null
+++ b/src/frame/role/UserRight.java
@@ -0,0 +1,19 @@
+package frame.role;
+
+import frame.object.data.IFilterSegmentProvider;
+import frame.object.http.Path;
+
+public class UserRight implements IFilterSegmentProvider {
+
+	public boolean isValid(Path path) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public String getFilterValue() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/src/frame/role/UserRightContainer.java b/src/frame/role/UserRightContainer.java
new file mode 100644
index 0000000..1ab2bc0
--- /dev/null
+++ b/src/frame/role/UserRightContainer.java
@@ -0,0 +1,90 @@
+package frame.role;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import frame.object.http.Path;
+import frame.util.Util;
+
+
+public class UserRightContainer {
+
+	private static UserRightContainer instance;
+	private Map<String, Role> roleMap;
+	private Map<String, String> dataFilterMap;
+	
+	public static synchronized UserRightContainer getInstance() {
+		if (instance == null) {
+			instance = new UserRightContainer();
+		}
+		
+		return instance;
+	}
+	
+	private UserRightContainer() {
+		roleMap = new HashMap<String, Role>();
+		dataFilterMap = new HashMap<String, String>();
+	}
+	
+	public boolean existsPageRight(String logcode, Path path) {
+		Role role = roleMap.get(logcode);
+		
+		if (role == null) {
+			return false;
+		}
+		
+		return role.containsPath(path);
+	}
+	
+	public boolean existsDataRight(String logcode, String data) {
+		Role role = roleMap.get(logcode);
+		
+		if (role == null) {
+			return false;
+		}
+		
+		return role.containsData(data);
+	}
+
+	public boolean existsCallRight(String logcode, Path path) {
+		return true;
+	}
+
+	public String getDataFilter(OnlineUser onlineUser, String data) {
+		String template = dataFilterMap.get(data);
+		
+		if (template == null) {
+			return null;
+		}
+		
+		return onlineUser.getRowfilter(data, template);
+	}
+	
+	public void addDataRight(String dataName, String where) {
+		if (Util.isEmptyStr(dataName) || Util.isEmptyStr(where)) {
+			return;
+		}
+		
+		dataName = dataName.toLowerCase();
+		
+		if (!dataFilterMap.containsKey(dataName)) {
+			dataFilterMap.put(dataName, where);
+		}
+	}
+
+	public void addRoleResource(String roleName, String resource) {
+		if (Util.isEmptyStr(roleName)) {
+			return;
+		}
+		
+		roleName = roleName.toLowerCase();
+		Role role = roleMap.get(roleName);
+		
+		if (role == null) {
+			role = new Role(roleName);
+			roleMap.put(roleName, role);
+		}
+		
+		role.addResource(resource);
+	}
+}
diff --git a/src/frame/role/UserVariantProvider.java b/src/frame/role/UserVariantProvider.java
new file mode 100644
index 0000000..5eb4b22
--- /dev/null
+++ b/src/frame/role/UserVariantProvider.java
@@ -0,0 +1,81 @@
+package frame.role;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import frame.config.Loader;
+import frame.expression.GlobalVariant;
+import frame.expression.IVariantRequestListener;
+import frame.expression.VariantExistsException;
+import frame.expression.VariantRequestParams;
+
+public class UserVariantProvider extends Loader implements IVariantRequestListener {
+
+	private static UserVariantProvider instance;
+	private List<String> variantNames;
+	
+	
+	public UserVariantProvider() {
+		variantNames = new ArrayList<String>();
+		initVariantNames();
+	}
+	
+	public static synchronized UserVariantProvider getInstance() throws VariantExistsException {
+		if (instance == null) {
+			instance = new UserVariantProvider();
+		}
+		
+		return instance;
+	}
+
+	@Override
+	public String getStringValue(String name, VariantRequestParams params) {
+		HttpServletRequest request = params.getRequest();
+		
+		if (request == null) {
+			return null;
+		}
+		
+		HttpSession session = request.getSession();
+		OnlineUser onlineUser = (OnlineUser) session.getAttribute(OnlineUser.class.getSimpleName());
+		
+		if ("user.id".equals(name)) {
+			return onlineUser.getId();
+		}
+		else if ("userid".equals(name)) {
+			return onlineUser.getId();
+		}
+		else if ("username".equals(name)) {
+			return onlineUser.getName();
+		}
+		else if ("user.name".equals(name)) {
+			return onlineUser.getName();
+		}
+		else if ("user.emp_name".equals(name)) {
+			return onlineUser.getEmp_name();
+		}
+		
+		return null;
+	}
+
+	@Override
+	public List<String> getVariantNames() {
+		return variantNames;
+	}
+	
+	public void initVariantNames() {
+		variantNames.add("user.id");
+		variantNames.add("userid");
+		variantNames.add("user.emp_name");		
+	}
+
+	@Override
+	public void load() throws Exception {
+		GlobalVariant.regist(instance);
+	}
+
+	
+}
diff --git a/src/frame/schedule/ExecuteResult.java b/src/frame/schedule/ExecuteResult.java
new file mode 100644
index 0000000..2824857
--- /dev/null
+++ b/src/frame/schedule/ExecuteResult.java
@@ -0,0 +1,7 @@
+package frame.schedule;
+
+public enum ExecuteResult {
+
+	Success, Fail, Skip
+	
+}
diff --git a/src/frame/schedule/IJob.java b/src/frame/schedule/IJob.java
new file mode 100644
index 0000000..47d728b
--- /dev/null
+++ b/src/frame/schedule/IJob.java
@@ -0,0 +1,37 @@
+package frame.schedule;
+
+import java.util.Date;
+
+import org.quartz.JobKey;
+import org.quartz.TriggerKey;
+
+public interface IJob {
+
+	static String Key_Job = "Job";
+	static String Key_Config = "Config";
+	
+	static int Max_TryTimes = 3;
+	static int Max_TryCycles = 2;
+	static int Minutes_IntervalCycle = 10;
+	
+	String getId();
+	
+	String getName();
+	
+	void begin(String taskId, Date beginTime);
+	
+	void succeed(String taskId, int tryTimes, int tryCycles, Date endTime);
+	
+	void fail(String taskId, int tryTimes, int tryCycles, Date endTime);
+
+	void execute() throws Exception;
+
+	String getRunTime();
+
+	JobKey getJobKey();
+	
+	TriggerKey getTriggerKey();
+
+	JobStatus getStatus();
+	
+}
diff --git a/src/frame/schedule/ITask.java b/src/frame/schedule/ITask.java
new file mode 100644
index 0000000..0ab312b
--- /dev/null
+++ b/src/frame/schedule/ITask.java
@@ -0,0 +1,7 @@
+package frame.schedule;
+
+public interface ITask {
+	
+	void exec();
+	
+}
diff --git a/src/frame/schedule/Job.java b/src/frame/schedule/Job.java
new file mode 100644
index 0000000..75e19ba
--- /dev/null
+++ b/src/frame/schedule/Job.java
@@ -0,0 +1,82 @@
+package frame.schedule;
+
+import org.apache.log4j.Logger;
+import org.quartz.JobKey;
+import org.quartz.TriggerKey;
+
+
+public abstract class Job implements IJob {
+
+	protected static Logger logger;
+	private Object lock = new Object();
+	private JobStatus status;
+	protected String group;
+	protected String id;
+	protected String name;
+	protected String runtime;
+	protected JobKey jobKey;
+	protected TriggerKey triggerKey;
+	
+	static {
+		logger = Logger.getLogger(Job.class);
+	}
+	
+	public Job(String group, String id) {
+		this.group = group;
+		this.id = id;
+		
+		jobKey = new JobKey(id, group);
+		triggerKey = new TriggerKey(id, group);
+		status = JobStatus.Idle;
+	}
+	
+	public void execute() throws Exception {
+		if (JobStatus.Idle == status || JobStatus.Error == status) {
+			synchronized (lock) {
+				if (JobStatus.Idle == status || JobStatus.Error == status) {
+					doExecute();				
+				}
+				else {
+					logger.info(name + "鑷姩閫�鍑烘湰娆¤繍琛岋紝鍓嶄竴娆¤繍琛岀姸鎬侊細" + status);
+				}
+			}
+		}
+		else {
+			logger.info(name + "鑷姩閫�鍑烘湰娆¤繍琛岋紝鍓嶄竴娆¤繍琛岀姸鎬侊細" + status);
+		}		
+	}
+
+	protected abstract void doExecute() throws Exception;
+
+	public String getId() {
+		return id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getRunTime() {
+		return runtime;
+	}
+
+	public JobKey getJobKey() {
+		return jobKey;
+	}
+
+	public TriggerKey getTriggerKey() {
+		return triggerKey;
+	}
+
+	public JobStatus getStatus() {
+		return status;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setRuntime(String runtime) {
+		this.runtime = runtime;
+	}
+}
diff --git a/src/frame/schedule/JobStatus.java b/src/frame/schedule/JobStatus.java
new file mode 100644
index 0000000..654de9c
--- /dev/null
+++ b/src/frame/schedule/JobStatus.java
@@ -0,0 +1,6 @@
+package frame.schedule;
+
+public enum JobStatus {
+
+	Idle, Working, Error
+}
diff --git a/src/frame/schedule/Schedule.java b/src/frame/schedule/Schedule.java
new file mode 100644
index 0000000..25211cd
--- /dev/null
+++ b/src/frame/schedule/Schedule.java
@@ -0,0 +1,112 @@
+package frame.schedule;
+
+import org.apache.log4j.Logger;
+import org.quartz.CronScheduleBuilder;
+import org.quartz.CronTrigger;
+import org.quartz.JobBuilder;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.JobKey;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.SchedulerFactory;
+import org.quartz.Trigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.TriggerKey;
+import org.quartz.impl.StdSchedulerFactory;
+
+import frame.config.Configer;
+
+
+public class Schedule {
+	private static Logger logger;
+	private static Scheduler scheduler;
+	public static boolean Terminated;
+	
+	static {
+		logger = Logger.getLogger(Schedule.class);
+		Terminated = false;
+	}
+	
+	
+	public static void startup() {
+	    try {
+			SchedulerFactory factory = new StdSchedulerFactory(Configer.getPath_TimerConfig());
+			scheduler = factory.getScheduler();
+		} catch (Exception e) {
+			logger.error(e.getMessage());
+		}
+	}
+	
+	public static void shutdown() {
+		if (scheduler == null) {
+			return;
+		}
+		
+		try {
+			Terminated = true;
+			scheduler.shutdown();
+		}
+		catch (Exception e) {
+			logger.error(e);
+		}
+	}
+	
+	public static void appendJob(IJob job) throws Exception {
+		String runTime = job.getRunTime();
+		
+		if (runTime == null) {
+			return;
+		}
+		
+		JobKey jobKey = job.getJobKey();
+	    JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(jobKey).build();
+	    
+	    JobDataMap dataMap = jobDetail.getJobDataMap();
+	    dataMap.put(IJob.Key_Job, job);
+	    
+	    TriggerKey triggerKey = job.getTriggerKey();
+	    TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
+	    triggerBuilder.withIdentity(triggerKey);
+	    triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(runTime));
+	    CronTrigger trigger = (CronTrigger)triggerBuilder.build();
+
+	    if (!scheduler.checkExists(jobKey)) {
+		    scheduler.scheduleJob(jobDetail, trigger);
+	    }
+	}
+
+	public static void deleteJob(IJob job) throws SchedulerException {
+		JobKey jobKey = job.getJobKey();
+		
+		if (scheduler.checkExists(jobKey)) {
+			scheduler.deleteJob(jobKey);
+		}
+	}
+	
+	public void start() throws SchedulerException {
+		scheduler.start();
+	}
+	
+	public void pause() throws SchedulerException {
+		scheduler.pauseAll();
+	}
+	
+	public void clear() throws SchedulerException {
+		scheduler.clear();
+	}
+	
+	public void isStarted() throws SchedulerException {
+		scheduler.isStarted();
+	}
+	
+	public void isShutdown() throws SchedulerException {
+		scheduler.isShutdown();
+	}
+
+	public static boolean isActive() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+}
diff --git a/src/frame/schedule/ScheduleJob.java b/src/frame/schedule/ScheduleJob.java
new file mode 100644
index 0000000..c6ac0cb
--- /dev/null
+++ b/src/frame/schedule/ScheduleJob.java
@@ -0,0 +1,119 @@
+package frame.schedule;
+
+
+import java.util.Date;
+
+import org.apache.log4j.Logger;
+import org.quartz.Job;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+import frame.util.Util;
+
+
+
+
+public class ScheduleJob implements Job{
+	
+	protected static Logger logger;
+	
+	private Object lock = new Object();
+	private int tryTimes;
+	private int tryCycles;
+	private Date beginTime;
+	private Date endTime;
+	private boolean success;
+	
+	
+	static {
+		logger = Logger.getLogger(ScheduleJob.class);
+	}
+	
+	public void execute(JobExecutionContext context) throws JobExecutionException {
+		JobDetail jobDetail = context.getJobDetail();
+		JobDataMap dataMap = jobDetail.getJobDataMap();
+		
+		IJob job = (IJob)dataMap.get(IJob.Key_Job);
+		
+		synchronized (lock) {
+			JobStatus status = job.getStatus();
+
+			if (JobStatus.Idle == status) {
+				String taskId = Util.newShortGUID();
+				
+				beforeExecute(job, taskId);
+				try {
+					executeJob(job, taskId);
+				}
+				finally {
+					afterExecute(job, taskId);
+				}
+			}
+		}
+	}
+
+	private void beforeExecute(IJob job, String taskId) {
+		success = false;
+		beginTime = new Date();
+		tryTimes = 0;
+		tryCycles = 0;	
+				
+		job.begin(taskId, beginTime);
+	}
+	private void afterExecute(IJob job, String taskId) {
+		if (success) {
+			job.succeed(taskId, tryTimes, tryCycles, endTime);
+		}
+		else {
+			job.fail(taskId, tryTimes, tryCycles, endTime);
+		}
+	}
+	
+	private void executeJob(IJob job, String taskId) {
+		int cnt = 0;
+		String name = job.getName();
+		
+		for (int j = 0; j < IJob.Max_TryCycles; j++) {
+			tryCycles++;
+			
+			for (int i = 0; i < IJob.Max_TryTimes; i++) {
+				if (Schedule.Terminated) {
+					break;
+				}
+				
+				tryTimes++;
+				
+				try {
+					cnt = cnt + 1;
+					logger.info(name + "灏濊瘯绗�" + cnt + "娆¤繍琛�...");
+					
+					job.execute();
+					
+					success = true;
+					break;
+				}
+				catch (Exception e) {
+				}
+			}
+			
+			if (success) {
+				break;
+			}
+			
+			try {
+				int waitfor = 60 * IJob.Minutes_IntervalCycle;
+				
+				for (int w = 0; w < waitfor; w++) {
+					Thread.sleep(1000);
+					
+					if (Schedule.Terminated) {
+						break;
+					}
+				}
+			} catch (InterruptedException e) {
+			}				
+		}		
+	}
+}
diff --git a/src/frame/schedule/Timer.java b/src/frame/schedule/Timer.java
new file mode 100644
index 0000000..47d1c88
--- /dev/null
+++ b/src/frame/schedule/Timer.java
@@ -0,0 +1,24 @@
+package frame.schedule;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class Timer {
+	private ScheduledExecutorService service;
+
+	public void start(final ITask task, long delay, long period) {
+		Runnable runnable = new Runnable() {
+			public void run() {
+				task.exec();
+			}
+		};
+
+		service = Executors.newSingleThreadScheduledExecutor();
+		service.scheduleAtFixedRate(runnable, delay, period, TimeUnit.SECONDS);
+	}
+
+	public void end() {
+		service.shutdown();
+	}
+}
diff --git a/src/frame/server/ContextListener.java b/src/frame/server/ContextListener.java
new file mode 100644
index 0000000..7ce0551
--- /dev/null
+++ b/src/frame/server/ContextListener.java
@@ -0,0 +1,26 @@
+package frame.server;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.log4j.PropertyConfigurator;
+
+import frame.config.Configer;
+
+public class ContextListener implements ServletContextListener {
+
+	public ContextListener() {
+
+	}
+
+	public void contextInitialized(ServletContextEvent event) {
+		Configer.init(event.getServletContext());
+		PropertyConfigurator.configure(Configer.getPath_LoggerConfig());
+		ServerInstance.startService();
+	}
+
+	public void contextDestroyed(ServletContextEvent arg0) {
+		ServerInstance.stopService();
+	}
+
+}
diff --git a/src/frame/server/DataSourceLoader.java b/src/frame/server/DataSourceLoader.java
new file mode 100644
index 0000000..f392cbb
--- /dev/null
+++ b/src/frame/server/DataSourceLoader.java
@@ -0,0 +1,5 @@
+package frame.server;
+
+public class DataSourceLoader {
+
+}
diff --git a/src/frame/server/Dispatcher.java b/src/frame/server/Dispatcher.java
new file mode 100644
index 0000000..873cfd5
--- /dev/null
+++ b/src/frame/server/Dispatcher.java
@@ -0,0 +1,333 @@
+package frame.server;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.log4j.Logger;
+
+import frame.call.writer.EnvelopWriter;
+import frame.call.writer.IEnvelop;
+import frame.config.Configer;
+import frame.role.OnlineAnymous;
+import frame.role.OnlineUser;
+import frame.role.Statistics;
+import frame.util.Util;
+
+
+public class Dispatcher implements Filter {
+
+	private static Dispatcher instance;
+	private static Logger logger;
+	private static String contextPath;
+	private static boolean AuthorizeActive;
+	private static Set<String> freeVisitTypes;
+	private static ResourceFilter freeVisitResources;
+	private static Set<String> freeVisitCalls;
+	private static Map<String, VirtualPath> virtualPaths;
+	private static Map<String, Class<? extends ICallObject>> callableClassMap;
+	private static ExcludeList excludeList;
+
+	static {
+		logger = Logger.getLogger(Dispatcher.class);
+
+		callableClassMap = new HashMap<String, Class<? extends ICallObject>>();
+		freeVisitTypes = new HashSet<String>();
+		freeVisitResources = new ResourceFilter();
+		virtualPaths = new HashMap<String, VirtualPath>();
+		freeVisitCalls = new HashSet<String>();
+		excludeList = new ExcludeList();
+	}
+
+	public Dispatcher() {
+		instance = this;
+	}
+
+	public synchronized static Dispatcher getInstance() {
+		if (instance == null) {
+			instance = new Dispatcher();
+		}
+
+		return instance;
+	}
+
+	public void init(FilterConfig filterConfig) throws ServletException {
+		ServletContext servletContext = filterConfig.getServletContext();
+		Map<String, Statistics> visitor = new HashMap<String, Statistics>();
+		servletContext.setAttribute("visitor", visitor);
+
+		contextPath = servletContext.getContextPath();
+		RequestPath.contextLength = contextPath.length();
+		logger.debug("contextPath: " + contextPath);
+
+		AuthorizeActive = Util.stringToBoolean(Configer.getParam("AuthorizeActive"));
+	}
+
+	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
+		HttpServletRequest request = (HttpServletRequest) req;
+		HttpServletResponse response = (HttpServletResponse) res;
+		
+		request.setCharacterEncoding("utf-8");
+		saveIp(request, getIP(request));
+
+		try {
+			RequestPath path = new RequestPath(request);
+			RequestType type = path.getType();
+
+			if (logger.isDebugEnabled()) {
+				logger.debug("filter request URI:" + path);
+			}
+
+			if (RequestType.Resource == type) {
+				// 1.1 goto free resource
+				if (freeVisitTypes.contains(path.getSuffix())) {
+					RequestDispatcher dispatcher = request.getRequestDispatcher(path.getTarget());
+					dispatcher.forward(request, response);
+					return;
+				}
+				// 1.2 goto free sub resource
+				else if (freeVisitResources.contains(path.getTarget())) {
+					RequestDispatcher dispatcher = request.getRequestDispatcher(path.getTarget());
+					dispatcher.forward(request, response);
+					return;
+				}
+				// 1.3 goto authorized resources
+				else {
+					OnlineUser onlineUser = getOnlineUser(path);
+					if (onlineUser == null) {
+						String target = Configer.getPage_TimeOut();
+
+						PrintWriter out = response.getWriter();
+						out.println("<script>");
+						out.println("window.top.location.href='" + target + "'");
+						out.println("</script>");
+						return;
+					}
+
+					RequestDispatcher dispatcher = request.getRequestDispatcher(path.getTarget());
+					dispatcher.forward(request, response);					
+				}
+			}
+			else {
+				VirtualPath virtualPath = virtualPaths.get(path.getTarget());
+
+				if (virtualPath != null) {
+					logger.debug("get virtual path: " + virtualPath);
+
+					//2.1 goto root
+					if (RequestType.Root == type) {
+						response.sendRedirect(virtualPath.getTarget());
+						return;
+					}
+					//2.2 goto resource
+					else if (VirtualPathType.Resource == virtualPath.getType()) {
+						// 4. goto resource on virtual path
+						RequestDispatcher dispatcher = request.getRequestDispatcher(virtualPath.getTarget());
+						dispatcher.forward(request, response);
+						return;
+					}
+					//2.3 goto error
+					else {
+						writeError(request, response, "resource not exists: " + path.getTarget());
+						return;
+					}
+				}
+
+				virtualPath = virtualPaths.get(path.getParent());
+
+				if (virtualPath == null) {
+					if (excludeList.contains(path)) {
+						logger.debug("dispatch exclude url:" + path);
+						chain.doFilter(request, response);
+					}
+				}
+				
+				if (virtualPath == null) {
+					writeError(request, response, "resource not exists: " + path.getTarget());
+					return;
+				}
+
+				Class<? extends ICallObject> clazz = virtualPath.getCallableClass();
+				ICallObject callable = clazz.newInstance();
+				callable.setRequest(request);
+				callable.setResponse(response);
+
+				OnlineUser onlineUser = getOnlineUser(path);
+
+				// 3.1 goto free visit object
+				if (onlineUser == null) {
+					if (freeVisitCalls.contains(path.getTarget())) {
+						onlineUser = OnlineAnymous.getInstance();
+					}
+					else {
+						writeSessionTimeout(request, response);
+						return;
+					}
+				}
+
+				// 3.2 goto authorized object
+				callable.setOnlineUser(onlineUser);
+				callable.receive(path.getShortTarget());
+				return;
+			}
+		}
+		catch (Exception e) {
+			String error = printStackToString(e);
+			logger.error("dispatch error:" + e.getMessage());
+			logger.error(error);
+			writeError(request, response, error);
+		}
+	}
+
+	private OnlineUser getOnlineUser(RequestPath path) {
+		HttpServletRequest request = path.getRequest();
+		HttpSession session = request.getSession();
+
+		// 鑾峰彇OnlineUser绫荤殑绠�鍗曠被鍚�
+		String code = OnlineUser.class.getSimpleName();
+		OnlineUser onlineUser = (OnlineUser) session.getAttribute(code);
+
+		// 濡傛灉session涓病鏈夌敤鎴蜂俊鎭紝浣嗘槸涓嶈鏉冮檺楠岃瘉锛岃矗杩斿洖涓�涓尶鍚嶇殑鐢ㄦ埛淇℃伅锛屼互渚胯繘琛屼笅闈㈢殑鎿嶄綔
+		if (onlineUser == null) {
+			if (!AuthorizeActive) {
+				onlineUser = OnlineAnymous.getInstance();
+			}
+
+			return onlineUser;
+		}
+
+		// 濡傛灉闇�瑕佹潈闄愰獙璇侊紝濡傛灉鐪熸病鏈夌敤鎴蜂俊鎭紝灏嗚繑鍥瀗ull
+		return onlineUser;
+	}
+
+	public void destroy() {
+
+	}
+
+	private String printStackToString(Exception e) {
+		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+		PrintStream printStream = new PrintStream(outStream);
+		e.printStackTrace(printStream);
+
+		return outStream.toString();
+	}
+
+	private void writeSessionTimeout(HttpServletRequest request, HttpServletResponse response) {
+		try {
+			EnvelopWriter envelopWriter = new EnvelopWriter(request, response);
+			envelopWriter.ReplyError(IEnvelop.Error_Code_Timeout, IEnvelop.Error_Messgae_Timeout);
+		}
+		catch (Exception ex) {
+		}
+	}
+
+	private void writeError(HttpServletRequest request, HttpServletResponse response, String error) {
+		try {
+			EnvelopWriter envelopWriter = new EnvelopWriter(request, response);
+			envelopWriter.ReplyError(IEnvelop.Error_Code_ServerError, error);
+		}
+		catch (Exception ex) {
+		}
+	}
+
+	public void clear() {
+		callableClassMap.clear();
+	}
+
+	public void appendFreeVisitType(String type) {
+		type = type.toLowerCase();
+		freeVisitTypes.add(type);
+	}
+
+	public void appendFreeVisitResource(String resource) {
+		resource = resource.toLowerCase();
+		freeVisitResources.add(resource);
+	}
+
+	public void appendFreeVisitCalls(String call) {
+		call = call.toLowerCase();
+
+		if ('/' != call.charAt(0)) {
+			call = "/" + call;
+		}
+
+		freeVisitCalls.add(call);
+	}
+
+
+	public void appendExcludeResources(String exclude) {
+		exclude = exclude.toLowerCase();
+		excludeList.add(exclude);
+	}
+	
+	public void appendVirtualPaths(String path, String target, String className) throws Exception {
+		if ('/' != path.charAt(0)) {
+			path = "/" + path;
+		}
+
+		VirtualPath virtualPath = new VirtualPath(target, className);
+		virtualPaths.put(path, virtualPath);
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public void appendCallableClass(String path, String classname) throws Exception {
+		path = path.toLowerCase();
+
+		Class clazz = Class.forName(classname);
+		Class<? extends ICallObject> callableClass = (Class<? extends ICallObject>) clazz;
+
+		callableClassMap.put(path, callableClass);
+	}
+	
+	private String getIP(HttpServletRequest request) {
+		String ip = request.getHeader("x-forwarded-for");
+
+		if (ip == null) {
+			ip = request.getRemoteAddr();
+			return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
+		}
+
+		return ip;
+	}
+
+	@SuppressWarnings("deprecation")
+	private void saveIp(HttpServletRequest request, String ip) {
+		if (!request.getRequestURI().endsWith(".html")) { // 涓嶅缃戦〉浠ュ鐨勮姹傚仛缁熻锛屼緥濡傚浘鐗囩瓑
+			return;
+		}
+		ServletContext servletContext = request.getServletContext();
+		@SuppressWarnings("unchecked")
+		Map<String, Statistics> visitor = (Map<String, Statistics>) servletContext.getAttribute("visitor");
+		if (visitor.keySet().contains(ip)) {
+			Statistics s = visitor.get(ip);
+			s.setCnt(s.getCnt() + 1);
+			s.setDate(new Date().toLocaleString());
+			visitor.put(ip, s);
+			
+			servletContext.setAttribute("visitor", visitor);
+		}
+		else {
+			visitor.put(ip, new Statistics(ip, 1, new Date().toLocaleString()));
+			servletContext.setAttribute("visitor", visitor);
+		}
+	}
+
+}
diff --git a/src/frame/server/ServerInstance.java b/src/frame/server/ServerInstance.java
new file mode 100644
index 0000000..2229de2
--- /dev/null
+++ b/src/frame/server/ServerInstance.java
@@ -0,0 +1,133 @@
+package frame.server;
+
+import org.apache.log4j.Logger;
+
+import frame.config.LoaderContainer;
+import frame.config.Configer;
+import frame.config.ILoader;
+import frame.config.ContextConfigerLoader;
+import frame.schedule.Schedule;
+
+public class ServerInstance {
+
+	private static Logger logger;
+	private static ServerInstance instance;
+	private String version;
+	public static boolean Terminated;
+
+	static {
+		logger = Logger.getLogger(ServerInstance.class);
+	}
+	
+	public ServerInstance() {
+		version = "1.0.0.1";
+	}
+
+	public static void startService() {
+		try {
+			instance = new ServerInstance();
+			instance.start();
+		} 
+		catch (Exception e) {
+			logger.error(e);
+			e.printStackTrace();
+		}
+	}
+
+	public static void stopService() {
+		try {
+			instance.stop();
+		} catch (Exception e) {
+			logger.error(e);
+			e.printStackTrace();
+		}
+	}
+
+	public void start() throws Exception {
+		try {
+			logger.info("server is startting...");
+			logger.debug("server root path is " + Configer.getPath_Application());
+
+			ContextConfigerLoader configerLoader = ContextConfigerLoader.getInstance();
+			configerLoader.load();
+
+			LoaderContainer loaderContainer = LoaderContainer.getInstance();
+
+			for (ILoader loader : loaderContainer) {
+				if (loader.isActive()) {
+					logger.info("load config " + loader.getName());
+					loader.load();
+				} 
+				else {
+					logger.info("loader [" + loader.getName() + "] is not acitve");
+				}
+			}
+			
+			configerLoader.loadClasses();
+		} 
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+		finally {
+			printStartUpMessage();
+		}
+	}
+
+	public void stop() {
+		logger.info("internal server is stopping...");
+
+		if (Schedule.isActive()) {
+			Schedule.shutdown();
+		}
+
+		logger.info("internal server has been stopped");
+	}
+
+	public void restart() throws Exception {
+		stop();
+		start();
+	}
+
+	private static String echoString(String word, int count) {
+		StringBuilder result = new StringBuilder();
+
+		for (int i = 1; i <= count; i++) {
+			result.append(word);
+		}
+
+		return result.toString();
+	}
+
+	private void printStartUpMessage() {
+		int length_total = 40;
+
+		long total = Math.round((Runtime.getRuntime().totalMemory()) / (1024.0 * 1024));
+		long max = Math.round((Runtime.getRuntime().maxMemory()) / (1024.0 * 1024));
+
+		String envirenment = Configer.getParam("EnvironmentName");
+		System.out.println("--->>> " + envirenment + " --->>>");
+
+		System.out.println(echoString("*", length_total + 2));
+		printMessage("Total Memory:" + total + "M", length_total);
+		printMessage("Max Memory:" + max + "M", length_total);
+		printMessage(version, length_total);
+		System.out.println(echoString("*", length_total + 2));
+	}
+
+	private void printMessage(String message, int totalLength) {
+		MessagePos messagePos = new MessagePos(totalLength, message);
+		System.out.println("*" + echoString(" ", messagePos.length_begin) + message + echoString(" ", messagePos.length_end) + "*");
+	}
+
+	private class MessagePos {
+		private int length_begin;
+		private int length_end;
+		private int length_message;
+
+		public MessagePos(int totalLength, String message) {
+			length_message = message.length();
+			length_begin = (totalLength - length_message) / 2;
+			length_end = totalLength - length_begin - length_message;
+		}
+	}
+}
diff --git a/src/frame/util/ContentBuilder.java b/src/frame/util/ContentBuilder.java
new file mode 100644
index 0000000..4097146
--- /dev/null
+++ b/src/frame/util/ContentBuilder.java
@@ -0,0 +1,83 @@
+package frame.util;
+
+public class ContentBuilder {
+
+	protected StringBuilder content;
+	protected boolean empty;
+	protected String division;
+	
+	
+	public ContentBuilder() {
+		empty = true;
+		content = new StringBuilder();
+	}
+	
+	public ContentBuilder(String division) {
+		this.empty = true;
+		this.division = division;
+		this.content = new StringBuilder();
+	}
+	
+	public ContentBuilder append(Object data) {
+		if (data == null) {
+			return this;
+		}
+		
+		return append(data.toString());
+	}
+	
+	public ContentBuilder append(String data) {
+		if (division != null) {
+			if (empty) {
+				empty = false;
+			}
+			else {
+				content.append(division);
+			}			
+		}
+		
+		content.append(data);
+		return this;
+	}
+	
+	public ContentBuilder append(Object data, String division) {
+		if (data == null) {
+			return this;
+		}
+		
+		return append(data.toString(), division);
+	}
+	
+	public ContentBuilder append(String data, String division) {
+		if (empty) {
+			empty = false;
+		}
+		else {
+			content.append(division);
+		}
+		
+		content.append(data);
+		return this;
+	}
+	
+	public ContentBuilder append(char[] data) {
+		return append(data, 0, data.length);
+	}
+	
+	public ContentBuilder append(char[] data, int begin, int length) {
+		content.append(data, begin, length);
+		return this;
+	}
+	
+	public String toString() {
+		return content.toString();
+	}
+	
+	public boolean isEmpty() {
+		return empty;
+	}
+	
+	public void setEmpty(boolean empty) {
+		this.empty = empty;
+	}
+}
diff --git a/src/frame/util/MapList.java b/src/frame/util/MapList.java
new file mode 100644
index 0000000..af580f4
--- /dev/null
+++ b/src/frame/util/MapList.java
@@ -0,0 +1,194 @@
+package frame.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+public class MapList<T> implements Collection<T> {
+
+	protected List<T> itemList;
+	protected Map<Object, T> itemMap;
+	
+	public MapList() {
+		itemList = new ArrayList<T>();
+		itemMap = new HashMap<Object, T>();
+	}
+	
+	public void addAll(Map<Object, T> map) {
+		Set<Object> keys = map.keySet();
+		
+		for (Object key: keys) {
+			add(key, map.get(key));
+		}
+	}
+	
+	public void add(Object key, T item) {
+		itemList.add(item);
+		
+		if (key == null) {
+			key = "empty";
+		}
+		
+		if (key instanceof String) {
+			key = ((String) key).toLowerCase();
+		}
+		
+		itemMap.put(key, item);
+	}
+	
+	public T get(String key) {
+		if (key == null) {
+			key = "empty";
+		}
+		key = key.toLowerCase();
+		
+		return itemMap.get(key);
+	}
+	
+	public T remove(String key) {
+		if (key == null) {
+			return null;
+		}
+		
+		T obj = itemMap.get(key.toLowerCase());
+		
+		if (obj != null) {
+			itemMap.remove(key);
+			itemList.remove(obj);
+		}
+		
+		return obj;
+	}
+	
+	public List<T> getItemList() {
+		return itemList;
+	}
+
+	public boolean isEmpty() {
+		return itemList.isEmpty();
+	}
+	
+	public int size() {
+		return itemList.size();
+	}
+	
+	public int mapSize() {
+		return itemMap.size();
+	}
+	
+	@Override
+	public Iterator<T> iterator() {
+		return itemList.iterator();
+	}
+
+	public void clear() {
+		itemList.clear();
+		itemMap.clear();
+	}
+	
+	public String toString(String separator) {
+		ContentBuilder builder = new ContentBuilder(separator);
+		
+		for (Object key: itemMap.keySet()) {
+			builder.append(key);
+		}
+		
+		return builder.toString();
+	}
+	
+	public Set<Object> keySet() {
+		return itemMap.keySet();
+	}
+
+	public boolean equals(MapList<T> another) {
+		if (another == null) {
+			return false;
+		}
+		
+		if (this == another) {
+			return true;
+		}
+		
+		Set<Object> keys = itemMap.keySet();
+		for (Object key: keys) {
+			if (!another.contains(key)) {
+				return false;
+			}
+		}
+		
+		Set<Object> anotherKeys = another.itemMap.keySet();
+		for (Object anotherKey: anotherKeys) {
+			if (!contains(anotherKey)) {
+				return false;
+			}
+		}
+		
+		return true;
+	}
+
+	@Override
+	public boolean contains(Object key) {
+		if (key == null) {
+			return false;
+		}
+		
+		if (key instanceof String) {
+			key = ((String)key).toLowerCase();
+		}
+
+		return itemMap.containsKey(key);
+	}
+
+	@Override
+	public Object[] toArray() {
+		return itemList.toArray();
+	}
+
+	@SuppressWarnings("hiding")
+	@Override
+	public <T> T[] toArray(T[] a) {
+		return itemList.toArray(a);
+	}
+
+	@Override
+	public boolean add(T e) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends T> c) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}
diff --git a/src/frame/util/MapTree.java b/src/frame/util/MapTree.java
new file mode 100644
index 0000000..c1bca8c
--- /dev/null
+++ b/src/frame/util/MapTree.java
@@ -0,0 +1,105 @@
+package frame.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeSet;
+
+import org.apache.log4j.Logger;
+
+public class MapTree<T> implements Iterable<T> {
+
+	protected static Logger logger;
+	protected TreeSet<T> itemList;
+	protected Map<String, T> itemMap;
+	
+	static {
+		logger = Logger.getLogger(MapTree.class);
+	}
+	
+	public MapTree() {
+		itemList = new TreeSet<T>();
+		itemMap = new HashMap<String, T>();
+	}
+	
+	public void add(String key, T item) {
+		if (key == null) {
+			key = "empty";
+		}
+		key = key.toLowerCase();
+		
+		if (itemMap.containsKey(key)) {
+			logger.error("duplicate " + this.getClass().getName() +  " key: " + key);
+			return;
+		}
+		
+		itemMap.put(key, item);
+		itemList.add(item);
+	}
+	
+	public T get(String key) {
+		if (key == null) {
+			key = "empty";
+		}
+		key = key.toLowerCase();
+		
+		return itemMap.get(key);
+	}
+	
+	public T remove(String key) {
+		if (key == null) {
+			return null;
+		}
+		
+		T obj = itemMap.get(key.toLowerCase());
+		
+		if (obj != null) {
+			itemMap.remove(key);
+			itemList.remove(obj);
+		}
+		
+		return obj;
+	}
+	
+	public TreeSet<T> getItemList() {
+		return itemList;
+	}
+
+	public boolean isEmpty() {
+		return itemList.isEmpty();
+	}
+	
+	public int size() {
+		return itemList.size();
+	}
+	
+	public boolean containsKey(String key) {
+		if (key == null) {
+			return false;
+		}
+		
+		key = key.toLowerCase();
+		return itemMap.containsKey(key);
+	}
+
+	@Override
+	public Iterator<T> iterator() {
+		return itemList.iterator();
+	}
+
+	public void clear() {
+		itemList.clear();
+		itemMap.clear();
+	}
+	
+	public String toString(String separator) {
+		ContentBuilder builder = new ContentBuilder(separator);
+		
+		for (String key: itemMap.keySet()) {
+			builder.append(key);
+		}
+		
+		return builder.toString();
+	}
+	
+}
diff --git a/src/frame/util/Util.java b/src/frame/util/Util.java
new file mode 100644
index 0000000..1ce487a
--- /dev/null
+++ b/src/frame/util/Util.java
@@ -0,0 +1,548 @@
+package frame.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import frame.config.Configer;
+import frame.data.DataBaseType;
+
+public class Util {
+
+	public static final String TRUE = "T";
+	public static final String FALSE = "F";
+	public static final String String_Return = "\r\n";
+	public static final String String_Empty = "";
+
+	public static String newShortGUID() {
+		UUID uuid = UUID.randomUUID();
+		String strGUID;
+		String shortGUID;
+
+		strGUID = uuid.toString();
+		shortGUID = strGUID.substring(0, 8) + strGUID.substring(9, 13) + strGUID.substring(14, 18) + strGUID.substring(19, 23)
+				+ strGUID.substring(24, 36);
+
+		return shortGUID;
+	}
+
+	public static String quotedStr(String str) {
+		if (str != null)
+			return "'" + str + "'";
+		else
+			return "''";
+	}
+
+	public static String doubleQuotedStr(String str) {
+		if (str != null)
+			return "\"" + str + "\"";
+		else
+			return "\"\"";
+	}
+
+	public static String quotedLikeStr(String str) {
+		if (str != null)
+			return "'%" + str + "%'";
+		else
+			return "''";
+	}
+	
+	public static String[] split(String str) {
+		if (str == null) {
+			return new String[0];
+		}
+		
+		return str.replace(",", ";").replace("锛�", ";").replace("锛�", ";").split(";");
+	}
+
+	public static String newDBDateString() throws Exception {
+		Date date = new Date();
+		return newDBDateString(date);
+	}
+
+	public static String newDBDateString(Date date) throws Exception {
+		DataBaseType dbType = Configer.getDataBaseType();
+
+		if (DataBaseType.Oracle == dbType) {
+			return newOracleDateString(date);
+		}
+		else if (DataBaseType.SQLServer == dbType) {
+			return newSqlServerDateString(date);
+		}
+		else if (DataBaseType.MySQL == dbType) {
+			return newMySqlDateString(date);
+		}
+		else {
+			return DataTimeToString(date);
+		}
+	}
+
+	public static String toOracleDataStr(String dataStr) {
+		return "to_date('" + dataStr + "','YYYY-MM-DD HH24:MI:SS')";
+	}
+
+	public static String toMySQLDateStr(Date value) {
+		return DataTimeToString(value, "yyyy-MM-dd HH:mm:ss");
+	}
+
+	public static String DataTimeToString(Date value) {
+		return DataTimeToString(value, "yyyy-MM-dd HH:mm:ss");
+	}
+
+	public static String DataTimeToString(Date value, String format) {
+		if (value == null) {
+			return null;
+		}
+
+		String result = "";
+		DateFormat dateFormat = new SimpleDateFormat(format);
+		result = dateFormat.format(value);
+
+		return result;
+	}
+
+	public static String newDateStr() {
+		return newDateTimeStr("yyyy-MM-dd");
+	}
+
+	public static String newDateTimeStr() {
+		return newDateTimeStr("yyyy-MM-dd kk:mm:ss");
+	}
+
+	public static String newDateTimeStr(String fomater) {
+		return getDateTimeStr(new Date(), fomater);
+	}
+
+	public static String getDateTimeStr(Date date, String fomater) {
+		String result = "";
+		DateFormat dateFormat = new SimpleDateFormat(fomater);
+		result = dateFormat.format(date);
+
+		return result;
+	}
+
+	public static String booleanToStr(boolean value) {
+		if (value)
+			return "T";
+		else
+			return "F";
+	}
+
+	public static boolean isEmptyStr(Object str) {
+		boolean result = false;
+
+		if ((str == null) || ("".equals(str)))
+			result = true;
+
+		return result;
+	}
+	
+	public static String IfEmpetyStr(String str, String value) {
+		if (isEmptyStr(str)) {
+			return value;
+		}
+		
+		return str;
+	}
+
+	public static boolean isNull(String value) {
+		if ((value == null))
+			return true;
+
+		if ("".equals(value)) {
+			return true;
+		}
+
+		if (value.length() == 4) {
+			value = value.toLowerCase();
+			return "null".equals(value);
+		}
+
+		return false;
+	}
+
+	public static String UTF8decode(String str) {
+		if (!isUTF8Encoding(str))
+			return str;
+		byte[] bytes = str.getBytes();
+		ByteBuffer bb = ByteBuffer.wrap(bytes);
+		Charset csets = Charset.forName("UTF-8");
+		CharBuffer c = csets.decode(bb);
+		return c.toString();
+	}
+
+	private static boolean isUTF8Encoding(String str) {
+		byte[] bytes = str.getBytes();
+		for (int i = 0; i < bytes.length; i++) {
+			int byteLen = Byte.toString(bytes[i]).length();
+			if (byteLen == 4)
+				return true;
+			else
+				continue;
+		}
+		return false;
+	}
+
+	public static boolean stringToBoolean(String value) {
+		if (value != null) {
+			value = value.toLowerCase();
+
+			if (value.equals("t")) {
+				return true;
+			}
+			else if (value.equals("y")) {
+				return true;
+			}
+			else if (value.equals("true")) {
+				return true;
+			}
+			else if (value.equals("yes")) {
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else
+			return false;
+	}
+
+	public static int stringToInt(String value, int defaultValue) {
+		if (value != null) {
+			try {
+				Double doubleValue = Double.valueOf(value);
+				return doubleValue.intValue();
+			}
+			catch (Exception e) {
+				return defaultValue;
+			}
+		}
+		else
+			return defaultValue;
+	}
+
+	public static BigDecimal stringToBigDecimal(String value, BigDecimal defaultValue) {
+		if (value == null) {
+			return defaultValue;
+		}
+
+		try {
+			BigDecimal decimalValue = BigDecimal.valueOf(Double.valueOf(value));
+			return decimalValue;
+		}
+		catch (Exception e) {
+			return defaultValue;
+		}
+	}
+
+	public static Date StringToDate(String str) throws ParseException {
+		if (Util.isEmptyStr(str)) {
+			return null;
+		}
+
+		Date result = null;
+		String fomater = null;
+		str = str.replace('T', ' ');
+
+		if (str.indexOf("/") == 4) {
+			fomater = "yyyy/MM/dd";
+		}
+		else if (str.indexOf("/") == 2 || str.indexOf("/") == 1) {
+			fomater = "MM/dd/yyyy";
+		}
+		else if (str.indexOf("-") == 2 || str.indexOf("-") == 1) {
+			fomater = "MM-dd-yyyy";
+		}
+		else if (str.indexOf("-") == 4 && str.indexOf(":") < 0) {
+			fomater = "yyyy-MM-dd";
+		}
+		else if (str.indexOf("-") == 4 && str.indexOf(":") > 0) {
+			if (str.split(":").length == 3) {
+				fomater = "yyyy-MM-dd HH:mm:ss";
+			}
+			else {
+				str = str + ":00";
+				fomater = "yyyy-MM-dd HH:mm:00";
+			}
+
+		}
+		else if (str.indexOf(".") == 2 || str.indexOf(".") == 1) {
+			fomater = "MM.dd.yyyy";
+		}
+		else if (str.indexOf(".") == 4) {
+			fomater = "yyyy.MM.dd";
+		}
+		else if (str.indexOf("-") < 0 && str.indexOf("/") < 0) {
+			fomater = "yyyyMMdd";
+		}
+
+		DateFormat dateFormat = new SimpleDateFormat(fomater);
+		result = dateFormat.parse(str);
+
+		return result;
+	}
+
+	public static Date doubleToDate(Double value) throws ParseException {
+		Date result = null;
+
+		if (value != null) {
+			if (value > 195000 && value <= 210001) {
+				value = value * 100 + 01;
+			}
+
+			if (value >= 19500101 && value <= 21000101) {
+				String value_Str = String.valueOf(value.intValue());
+				result = Util.StringToDate(value_Str);
+			}
+			else if (value > (1950 - 1900) * 365 && value < (2100 - 1900) * 365) {
+				int dateValue = value.intValue();
+				double secValue = value - dateValue;
+				Date dayDate = intToDate(dateValue);
+				long sec = Math.round(secValue * 24 * 3600 * 1000);
+
+				result = new Date();
+				result.setTime(dayDate.getTime() + sec);
+				return result;
+			}
+		}
+
+		return result;
+	}
+
+	public static Date intToDate(int value) {
+		Calendar result = Calendar.getInstance();
+		result.set(Calendar.YEAR, 1900);
+		result.set(Calendar.MONTH, 0);
+		result.set(Calendar.DAY_OF_MONTH, 1);
+		result.set(Calendar.HOUR_OF_DAY, 0);
+		result.set(Calendar.MINUTE, 0);
+		result.set(Calendar.SECOND, 0);
+
+		result.add(Calendar.DATE, value - 2);
+		return result.getTime();
+	}
+
+	public static int getArrayContentSize(Object[] datas) {
+		int result = 0;
+
+		for (int i = 0; i < datas.length; i++) {
+			if (datas[i] != null) {
+				result++;
+			}
+		}
+
+		return result;
+	}
+
+	public static String deleteSuffix(String name) {
+		String result = null;
+
+		if (!isEmptyStr(name)) {
+			int pos = name.lastIndexOf(".");
+			result = name.substring(0, pos);
+		}
+
+		return result;
+	}
+
+	public static String[] mergeArray(String[] array1, String[] array2) {
+		if (array1 == null) {
+			return array2;
+		}
+
+		if (array2 == null) {
+			return array2;
+		}
+
+		List<String> set = new ArrayList<String>(array1.length + array2.length);
+
+		for (int i = 0; i < array1.length; i++) {
+			set.add(array1[i]);
+		}
+
+		for (int i = 0; i < array2.length; i++) {
+			if (!set.contains(array2[i])) {
+				set.add(array2[i]);
+			}
+		}
+
+		String[] result = new String[0];
+		return set.toArray(result);
+	}
+
+	public static String newOracleDateString(Date date) {
+		String nowStr = "";
+		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		nowStr = dateFormat.format(date);
+
+		return "to_date('" + nowStr + "','YYYY-MM-DD HH24:MI:SS')";
+	}
+
+	public static String newMySqlDateString(Date date) {
+		String nowStr = "";
+		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		nowStr = dateFormat.format(date);
+
+		return "('" + nowStr + "')";
+	}
+
+	public static String newSqlServerDateString(Date date) {
+		String nowStr = "";
+		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		nowStr = dateFormat.format(date);
+
+		return "('" + nowStr + "')";
+	}
+
+	public static boolean isSameString(String value1, String value2) {
+		if (value1 == null) {
+			if (value2 == null) {
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			if (value2 == null) {
+				return false;
+			}
+			else {
+				return value1.equals(value2);
+			}
+		}
+	}
+
+	public static boolean isSameStringIgnoreCase(String value1, String value2) {
+		if (value1 == null) {
+			if (value2 == null) {
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			if (value2 == null) {
+				return false;
+			}
+			else {
+				return value1.equalsIgnoreCase(value2);
+			}
+		}
+	}
+
+	public static String toLowerCase(String name, String defaultValue) {
+		if (name == null) {
+			return defaultValue;
+		}
+		else {
+			return name.toLowerCase();
+		}
+	}
+
+	public static String getExceptionStack(Exception e) {
+		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+		PrintStream printStream = new PrintStream(outStream);
+		e.printStackTrace(printStream);
+
+		return outStream.toString();
+	}
+
+	public static Date getSpecialDayOffToday(int dayCount) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(new Date());
+		calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + dayCount);
+		return calendar.getTime();
+	}
+
+	public static String getPassWord(int length) {
+		int[] array = new int[length];
+		char[] chars = new char[length];
+		StringBuilder str = new StringBuilder();
+		int temp = 0;
+		for (int i = 0; i < length; i++) {
+			while (true) {
+				temp = (int) (Math.random() * 1000);
+				if (temp >= 48 && temp <= 57)
+					break;
+				if (temp >= 65 && temp <= 90)
+					break;
+				if (temp >= 97 && temp <= 122)
+					break;
+			}
+
+			array[i] = temp;
+			chars[i] = (char) array[i];
+			str.append(chars[i]);
+		}
+
+		return str.toString();
+	}
+
+	public static void main(String[] args) {
+		System.out.println(getPassWord(10));
+	}
+
+	public static String escapeQuoted(String filter) {
+		if (filter == null) {
+			return filter;
+		}
+
+		int length = filter.length();
+
+		if (length <= 1) {
+			return filter;
+		}
+
+		char first = filter.charAt(0);
+		char last = filter.charAt(length - 1);
+
+		if (('\'' == first || '"' == first) && (first == last)) {
+			filter = filter.substring(1, length - 1);
+			filter = filter.trim();
+			return filter;
+		}
+
+		return filter;
+	}
+
+	public static int[] getCurYearMonth() {
+		Date date = new Date();
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int year = calendar.get(Calendar.YEAR);
+		int month = calendar.get(Calendar.MONTH) + 1;
+		return new int[] { year, month };
+	}
+
+	public static String getTimeStamp(Date date) {
+		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		return dateFormat.format(date);
+	}
+
+	public static String getFileExt(String filename) {
+		int pos = filename.lastIndexOf(".");
+		String ext = filename.substring(pos);
+		return ext;
+	}
+
+	public static int getMonth(String value) throws ParseException {
+		Date date = StringToDate(value);
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return calendar.get(Calendar.MONTH) + 1;
+	}
+
+}

--
Gitblit v1.8.0