From 3555dd1c2c0f36ca564694a67d07454b934c1269 Mon Sep 17 00:00:00 2001
From: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date: Fri, 14 Dec 2012 11:50:56 +0100
Subject: [PATCH] add jquery plugins : bbq, formplugin and formwizard by
 Lingnan.

---
 .../erp5_jquery/jquery/plugin/bbq.xml         |   26 +
 .../erp5_jquery/jquery/plugin/bbq/bbq.js.xml  | 1182 +++++++++++++++++
 bt5/erp5_jquery_plugin_bbq/bt/change_log      |    2 +
 bt5/erp5_jquery_plugin_bbq/bt/copyright_list  |    1 +
 bt5/erp5_jquery_plugin_bbq/bt/dependency_list |    1 +
 bt5/erp5_jquery_plugin_bbq/bt/description     |    2 +
 bt5/erp5_jquery_plugin_bbq/bt/license         |    1 +
 bt5/erp5_jquery_plugin_bbq/bt/maintainer_list |    1 +
 bt5/erp5_jquery_plugin_bbq/bt/revision        |    1 +
 .../bt/template_format_version                |    1 +
 .../bt/template_path_list                     |    2 +
 bt5/erp5_jquery_plugin_bbq/bt/title           |    1 +
 bt5/erp5_jquery_plugin_bbq/bt/version         |    1 +
 .../erp5_jquery/jquery/plugin/formplugin.xml  |   26 +
 .../plugin/formplugin/formplugin.js.xml       |  719 ++++++++++
 .../bt/change_log                             |    2 +
 .../bt/copyright_list                         |    1 +
 .../bt/dependency_list                        |    1 +
 .../bt/description                            |    2 +
 bt5/erp5_jquery_plugin_formplugin/bt/license  |    1 +
 .../bt/maintainer_list                        |    1 +
 bt5/erp5_jquery_plugin_formplugin/bt/revision |    1 +
 .../bt/template_format_version                |    1 +
 .../bt/template_path_list                     |    2 +
 bt5/erp5_jquery_plugin_formplugin/bt/title    |    1 +
 bt5/erp5_jquery_plugin_formplugin/bt/version  |    1 +
 .../erp5_jquery/jquery/plugin/formwizard.xml  |   26 +
 .../plugin/formwizard/formwizard.js.xml       |  508 +++++++
 .../bt/change_log                             |    2 +
 .../bt/copyright_list                         |    1 +
 .../bt/dependency_list                        |    1 +
 .../bt/description                            |    2 +
 bt5/erp5_jquery_plugin_formwizard/bt/license  |    1 +
 .../bt/maintainer_list                        |    1 +
 bt5/erp5_jquery_plugin_formwizard/bt/revision |    1 +
 .../bt/template_format_version                |    1 +
 .../bt/template_path_list                     |    2 +
 bt5/erp5_jquery_plugin_formwizard/bt/title    |    1 +
 bt5/erp5_jquery_plugin_formwizard/bt/version  |    1 +
 39 files changed, 2529 insertions(+)
 create mode 100644 bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq.xml
 create mode 100644 bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq/bbq.js.xml
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/change_log
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/copyright_list
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/dependency_list
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/description
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/license
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/maintainer_list
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/revision
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/template_format_version
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/template_path_list
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/title
 create mode 100644 bt5/erp5_jquery_plugin_bbq/bt/version
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin.xml
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin/formplugin.js.xml
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/change_log
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/copyright_list
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/dependency_list
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/description
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/license
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/maintainer_list
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/revision
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/template_format_version
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/template_path_list
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/title
 create mode 100644 bt5/erp5_jquery_plugin_formplugin/bt/version
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard.xml
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard/formwizard.js.xml
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/change_log
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/copyright_list
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/dependency_list
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/description
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/license
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/maintainer_list
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/revision
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/template_format_version
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/template_path_list
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/title
 create mode 100644 bt5/erp5_jquery_plugin_formwizard/bt/version

diff --git a/bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq.xml b/bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq.xml
new file mode 100644
index 0000000000..7640b9865d
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Folder" module="OFS.Folder"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>bbq</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq/bbq.js.xml b/bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq/bbq.js.xml
new file mode 100644
index 0000000000..fc9c31d328
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/bbq/bbq.js.xml
@@ -0,0 +1,1182 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_EtagSupport__etag</string> </key>
+            <value> <string>ts54098924.89</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>bbq.js</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>application/javascript</string> </value>
+        </item>
+        <item>
+            <key> <string>data</string> </key>
+            <value> <string encoding="cdata"><![CDATA[
+
+/*!\n
+ * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010\n
+ * http://benalman.com/projects/jquery-bbq-plugin/\n
+ * \n
+ * Copyright (c) 2010 "Cowboy" Ben Alman\n
+ * Dual licensed under the MIT and GPL licenses.\n
+ * http://benalman.com/about/license/\n
+ */\n
+\n
+// Script: jQuery BBQ: Back Button & Query Library\n
+//\n
+// *Version: 1.2.1, Last updated: 2/17/2010*\n
+// \n
+// Project Home - http://benalman.com/projects/jquery-bbq-plugin/\n
+// GitHub       - http://github.com/cowboy/jquery-bbq/\n
+// Source       - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.js\n
+// (Minified)   - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.min.js (4.0kb)\n
+// \n
+// About: License\n
+// \n
+// Copyright (c) 2010 "Cowboy" Ben Alman,\n
+// Dual licensed under the MIT and GPL licenses.\n
+// http://benalman.com/about/license/\n
+// \n
+// About: Examples\n
+// \n
+// These working examples, complete with fully commented code, illustrate a few\n
+// ways in which this plugin can be used.\n
+// \n
+// Basic AJAX     - http://benalman.com/code/projects/jquery-bbq/examples/fragment-basic/\n
+// Advanced AJAX  - http://benalman.com/code/projects/jquery-bbq/examples/fragment-advanced/\n
+// jQuery UI Tabs - http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/\n
+// Deparam        - http://benalman.com/code/projects/jquery-bbq/examples/deparam/\n
+// \n
+// About: Support and Testing\n
+// \n
+// Information about what version or versions of jQuery this plugin has been\n
+// tested with, what browsers it has been tested in, and where the unit tests\n
+// reside (so you can test it yourself).\n
+// \n
+// jQuery Versions - 1.3.2, 1.4.1, 1.4.2\n
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4,\n
+//                   Chrome 4-5, Opera 9.6-10.1.\n
+// Unit Tests      - http://benalman.com/code/projects/jquery-bbq/unit/\n
+// \n
+// About: Release History\n
+// \n
+// 1.2.1 - (2/17/2010) Actually fixed the stale window.location Safari bug from\n
+//         <jQuery hashchange event> in BBQ, which was the main reason for the\n
+//         previous release!\n
+// 1.2   - (2/16/2010) Integrated <jQuery hashchange event> v1.2, which fixes a\n
+//         Safari bug, the event can now be bound before DOM ready, and IE6/7\n
+//         page should no longer scroll when the event is first bound. Also\n
+//         added the <jQuery.param.fragment.noEscape> method, and reworked the\n
+//         <hashchange event (BBQ)> internal "add" method to be compatible with\n
+//         changes made to the jQuery 1.4.2 special events API.\n
+// 1.1.1 - (1/22/2010) Integrated <jQuery hashchange event> v1.1, which fixes an\n
+//         obscure IE8 EmulateIE7 meta tag compatibility mode bug.\n
+// 1.1   - (1/9/2010) Broke out the jQuery BBQ event.special <hashchange event>\n
+//         functionality into a separate plugin for users who want just the\n
+//         basic event & back button support, without all the extra awesomeness\n
+//         that BBQ provides. This plugin will be included as part of jQuery BBQ,\n
+//         but also be available separately. See <jQuery hashchange event>\n
+//         plugin for more information. Also added the <jQuery.bbq.removeState>\n
+//         method and added additional <jQuery.deparam> examples.\n
+// 1.0.3 - (12/2/2009) Fixed an issue in IE 6 where location.search and\n
+//         location.hash would report incorrectly if the hash contained the ?\n
+//         character. Also <jQuery.param.querystring> and <jQuery.param.fragment>\n
+//         will no longer parse params out of a URL that doesn\'t contain ? or #,\n
+//         respectively.\n
+// 1.0.2 - (10/10/2009) Fixed an issue in IE 6/7 where the hidden IFRAME caused\n
+//         a "This page contains both secure and nonsecure items." warning when\n
+//         used on an https:// page.\n
+// 1.0.1 - (10/7/2009) Fixed an issue in IE 8. Since both "IE7" and "IE8\n
+//         Compatibility View" modes erroneously report that the browser\n
+//         supports the native window.onhashchange event, a slightly more\n
+//         robust test needed to be added.\n
+// 1.0   - (10/2/2009) Initial release\n
+\n
+(function($,window){\n
+  \'$:nomunge\'; // Used by YUI compressor.\n
+  \n
+  // Some convenient shortcuts.\n
+  var undefined,\n
+    aps = Array.prototype.slice,\n
+    decode = decodeURIComponent,\n
+    \n
+    // Method / object references.\n
+    jq_param = $.param,\n
+    jq_param_fragment,\n
+    jq_deparam,\n
+    jq_deparam_fragment,\n
+    jq_bbq = $.bbq = $.bbq || {},\n
+    jq_bbq_pushState,\n
+    jq_bbq_getState,\n
+    jq_elemUrlAttr,\n
+    jq_event_special = $.event.special,\n
+    \n
+    // Reused strings.\n
+    str_hashchange = \'hashchange\',\n
+    str_querystring = \'querystring\',\n
+    str_fragment = \'fragment\',\n
+    str_elemUrlAttr = \'elemUrlAttr\',\n
+    str_location = \'location\',\n
+    str_href = \'href\',\n
+    str_src = \'src\',\n
+    \n
+    // Reused RegExp.\n
+    re_trim_querystring = /^.*\\?|#.*$/g,\n
+    re_trim_fragment = /^.*\\#/,\n
+    re_no_escape,\n
+    \n
+    // Used by jQuery.elemUrlAttr.\n
+    elemUrlAttr_cache = {};\n
+  \n
+  // A few commonly used bits, broken out to help reduce minified file size.\n
+  \n
+  function is_string( arg ) {\n
+    return typeof arg === \'string\';\n
+  };\n
+  \n
+  // Why write the same function twice? Let\'s curry! Mmmm, curry..\n
+  \n
+  function curry( func ) {\n
+    var args = aps.call( arguments, 1 );\n
+    \n
+    return function() {\n
+      return func.apply( this, args.concat( aps.call( arguments ) ) );\n
+    };\n
+  };\n
+  \n
+  // Get location.hash (or what you\'d expect location.hash to be) sans any\n
+  // leading #. Thanks for making this necessary, Firefox!\n
+  function get_fragment( url ) {\n
+    return url.replace( /^[^#]*#?(.*)$/, \'$1\' );\n
+  };\n
+  \n
+  // Get location.search (or what you\'d expect location.search to be) sans any\n
+  // leading #. Thanks for making this necessary, IE6!\n
+  function get_querystring( url ) {\n
+    return url.replace( /(?:^[^?#]*\\?([^#]*).*$)?.*/, \'$1\' );\n
+  };\n
+  \n
+  // Section: Param (to string)\n
+  // \n
+  // Method: jQuery.param.querystring\n
+  // \n
+  // Retrieve the query string from a URL or if no arguments are passed, the\n
+  // current window.location.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.param.querystring( [ url ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  url - (String) A URL containing query string params to be parsed. If url\n
+  //    is not passed, the current window.location is used.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (String) The parsed query string, with any leading "?" removed.\n
+  //\n
+  \n
+  // Method: jQuery.param.querystring (build url)\n
+  // \n
+  // Merge a URL, with or without pre-existing query string params, plus any\n
+  // object, params string or URL containing query string params into a new URL.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.param.querystring( url, params [, merge_mode ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  url - (String) A valid URL for params to be merged into. This URL may\n
+  //    contain a query string and/or fragment (hash).\n
+  //  params - (String) A params string or URL containing query string params to\n
+  //    be merged into url.\n
+  //  params - (Object) A params object to be merged into url.\n
+  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not\n
+  //    specified, and is as-follows:\n
+  // \n
+  //    * 0: params in the params argument will override any query string\n
+  //         params in url.\n
+  //    * 1: any query string params in url will override params in the params\n
+  //         argument.\n
+  //    * 2: params argument will completely replace any query string in url.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (String) Either a params string with urlencoded data or a URL with a\n
+  //    urlencoded query string in the format \'a=b&c=d&e=f\'.\n
+  \n
+  // Method: jQuery.param.fragment\n
+  // \n
+  // Retrieve the fragment (hash) from a URL or if no arguments are passed, the\n
+  // current window.location.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.param.fragment( [ url ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  url - (String) A URL containing fragment (hash) params to be parsed. If\n
+  //    url is not passed, the current window.location is used.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (String) The parsed fragment (hash) string, with any leading "#" removed.\n
+  \n
+  // Method: jQuery.param.fragment (build url)\n
+  // \n
+  // Merge a URL, with or without pre-existing fragment (hash) params, plus any\n
+  // object, params string or URL containing fragment (hash) params into a new\n
+  // URL.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.param.fragment( url, params [, merge_mode ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  url - (String) A valid URL for params to be merged into. This URL may\n
+  //    contain a query string and/or fragment (hash).\n
+  //  params - (String) A params string or URL containing fragment (hash) params\n
+  //    to be merged into url.\n
+  //  params - (Object) A params object to be merged into url.\n
+  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not\n
+  //    specified, and is as-follows:\n
+  // \n
+  //    * 0: params in the params argument will override any fragment (hash)\n
+  //         params in url.\n
+  //    * 1: any fragment (hash) params in url will override params in the\n
+  //         params argument.\n
+  //    * 2: params argument will completely replace any query string in url.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (String) Either a params string with urlencoded data or a URL with a\n
+  //    urlencoded fragment (hash) in the format \'a=b&c=d&e=f\'.\n
+  \n
+  function jq_param_sub( is_fragment, get_func, url, params, merge_mode ) {\n
+    var result,\n
+      qs,\n
+      matches,\n
+      url_params,\n
+      hash;\n
+    \n
+    if ( params !== undefined ) {\n
+      // Build URL by merging params into url string.\n
+      \n
+      // matches[1] = url part that precedes params, not including trailing ?/#\n
+      // matches[2] = params, not including leading ?/#\n
+      // matches[3] = if in \'querystring\' mode, hash including leading #, otherwise \'\'\n
+      matches = url.match( is_fragment ? /^([^#]*)\\#?(.*)$/ : /^([^#?]*)\\??([^#]*)(#?.*)/ );\n
+      \n
+      // Get the hash if in \'querystring\' mode, and it exists.\n
+      hash = matches[3] || \'\';\n
+      \n
+      if ( merge_mode === 2 && is_string( params ) ) {\n
+        // If merge_mode is 2 and params is a string, merge the fragment / query\n
+        // string into the URL wholesale, without converting it into an object.\n
+        qs = params.replace( is_fragment ? re_trim_fragment : re_trim_querystring, \'\' );\n
+        \n
+      } else {\n
+        // Convert relevant params in url to object.\n
+        url_params = jq_deparam( matches[2] );\n
+        \n
+        params = is_string( params )\n
+          \n
+          // Convert passed params string into object.\n
+          ? jq_deparam[ is_fragment ? str_fragment : str_querystring ]( params )\n
+          \n
+          // Passed params object.\n
+          : params;\n
+        \n
+        qs = merge_mode === 2 ? params                              // passed params replace url params\n
+          : merge_mode === 1  ? $.extend( {}, params, url_params )  // url params override passed params\n
+          : $.extend( {}, url_params, params );                     // passed params override url params\n
+        \n
+        // Convert params object to a string.\n
+        qs = jq_param( qs );\n
+        \n
+        // Unescape characters specified via $.param.noEscape. Since only hash-\n
+        // history users have requested this feature, it\'s only enabled for\n
+        // fragment-related params strings.\n
+        if ( is_fragment ) {\n
+          qs = qs.replace( re_no_escape, decode );\n
+        }\n
+      }\n
+      \n
+      // Build URL from the base url, querystring and hash. In \'querystring\'\n
+      // mode, ? is only added if a query string exists. In \'fragment\' mode, #\n
+      // is always added.\n
+      result = matches[1] + ( is_fragment ? \'#\' : qs || !matches[1] ? \'?\' : \'\' ) + qs + hash;\n
+      \n
+    } else {\n
+      // If URL was passed in, parse params from URL string, otherwise parse\n
+      // params from window.location.\n
+      result = get_func( url !== undefined ? url : window[ str_location ][ str_href ] );\n
+    }\n
+    \n
+    return result;\n
+  };\n
+  \n
+  jq_param[ str_querystring ]                  = curry( jq_param_sub, 0, get_querystring );\n
+  jq_param[ str_fragment ] = jq_param_fragment = curry( jq_param_sub, 1, get_fragment );\n
+  \n
+  // Method: jQuery.param.fragment.noEscape\n
+  // \n
+  // Specify characters that will be left unescaped when fragments are created\n
+  // or merged using <jQuery.param.fragment>, or when the fragment is modified\n
+  // using <jQuery.bbq.pushState>. This option only applies to serialized data\n
+  // object fragments, and not set-as-string fragments. Does not affect the\n
+  // query string. Defaults to ",/" (comma, forward slash).\n
+  // \n
+  // Note that this is considered a purely aesthetic option, and will help to\n
+  // create URLs that "look pretty" in the address bar or bookmarks, without\n
+  // affecting functionality in any way. That being said, be careful to not\n
+  // unescape characters that are used as delimiters or serve a special\n
+  // purpose, such as the "#?&=+" (octothorpe, question mark, ampersand,\n
+  // equals, plus) characters.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.param.fragment.noEscape( [ chars ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  chars - (String) The characters to not escape in the fragment. If\n
+  //    unspecified, defaults to empty string (escape all characters).\n
+  // \n
+  // Returns:\n
+  // \n
+  //  Nothing.\n
+  \n
+  jq_param_fragment.noEscape = function( chars ) {\n
+    chars = chars || \'\';\n
+    var arr = $.map( chars.split(\'\'), encodeURIComponent );\n
+    re_no_escape = new RegExp( arr.join(\'|\'), \'g\' );\n
+  };\n
+  \n
+  // A sensible default. These are the characters people seem to complain about\n
+  // "uglifying up the URL" the most.\n
+  jq_param_fragment.noEscape( \',/\' );\n
+  \n
+  // Section: Deparam (from string)\n
+  // \n
+  // Method: jQuery.deparam\n
+  // \n
+  // Deserialize a params string into an object, optionally coercing numbers,\n
+  // booleans, null and undefined values; this method is the counterpart to the\n
+  // internal jQuery.param method.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.deparam( params [, coerce ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  params - (String) A params string to be parsed.\n
+  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and\n
+  //    undefined to their actual value. Defaults to false if omitted.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (Object) An object representing the deserialized params string.\n
+  \n
+  $.deparam = jq_deparam = function( params, coerce ) {\n
+    var obj = {},\n
+      coerce_types = { \'true\': !0, \'false\': !1, \'null\': null };\n
+    \n
+    // Iterate over all name=value pairs.\n
+    $.each( params.replace( /\\+/g, \' \' ).split( \'&\' ), function(j,v){\n
+      var param = v.split( \'=\' ),\n
+        key = decode( param[0] ),\n
+        val,\n
+        cur = obj,\n
+        i = 0,\n
+        \n
+        // If key is more complex than \'foo\', like \'a[]\' or \'a[b][c]\', split it\n
+        // into its component parts.\n
+        keys = key.split( \'][\' ),\n
+        keys_last = keys.length - 1;\n
+      \n
+      // If the first keys part contains [ and the last ends with ], then []\n
+      // are correctly balanced.\n
+      if ( /\\[/.test( keys[0] ) && /\\]$/.test( keys[ keys_last ] ) ) {\n
+        // Remove the trailing ] from the last keys part.\n
+        keys[ keys_last ] = keys[ keys_last ].replace( /\\]$/, \'\' );\n
+        \n
+        // Split first keys part into two parts on the [ and add them back onto\n
+        // the beginning of the keys array.\n
+        keys = keys.shift().split(\'[\').concat( keys );\n
+        \n
+        keys_last = keys.length - 1;\n
+      } else {\n
+        // Basic \'foo\' style key.\n
+        keys_last = 0;\n
+      }\n
+      \n
+      // Are we dealing with a name=value pair, or just a name?\n
+      if ( param.length === 2 ) {\n
+        val = decode( param[1] );\n
+        \n
+        // Coerce values.\n
+        if ( coerce ) {\n
+          val = val && !isNaN(val)            ? +val              // number\n
+            : val === \'undefined\'             ? undefined         // undefined\n
+            : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null\n
+            : val;                                                // string\n
+        }\n
+        \n
+        if ( keys_last ) {\n
+          // Complex key, build deep object structure based on a few rules:\n
+          // * The \'cur\' pointer starts at the object top-level.\n
+          // * [] = array push (n is set to array length), [n] = array if n is \n
+          //   numeric, otherwise object.\n
+          // * If at the last keys part, set the value.\n
+          // * For each keys part, if the current level is undefined create an\n
+          //   object or array based on the type of the next keys part.\n
+          // * Move the \'cur\' pointer to the next level.\n
+          // * Rinse & repeat.\n
+          for ( ; i <= keys_last; i++ ) {\n
+            key = keys[i] === \'\' ? cur.length : keys[i];\n
+            cur = cur[key] = i < keys_last\n
+              ? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] )\n
+              : val;\n
+          }\n
+          \n
+        } else {\n
+          // Simple key, even simpler rules, since only scalars and shallow\n
+          // arrays are allowed.\n
+          \n
+          if ( $.isArray( obj[key] ) ) {\n
+            // val is already an array, so push on the next value.\n
+            obj[key].push( val );\n
+            \n
+          } else if ( obj[key] !== undefined ) {\n
+            // val isn\'t an array, but since a second value has been specified,\n
+            // convert val into an array.\n
+            obj[key] = [ obj[key], val ];\n
+            \n
+          } else {\n
+            // val is a scalar.\n
+            obj[key] = val;\n
+          }\n
+        }\n
+        \n
+      } else if ( key ) {\n
+        // No value was defined, so set something meaningful.\n
+        obj[key] = coerce\n
+          ? undefined\n
+          : \'\';\n
+      }\n
+    });\n
+    \n
+    return obj;\n
+  };\n
+  \n
+  // Method: jQuery.deparam.querystring\n
+  // \n
+  // Parse the query string from a URL or the current window.location,\n
+  // deserializing it into an object, optionally coercing numbers, booleans,\n
+  // null and undefined values.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.deparam.querystring( [ url ] [, coerce ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  url - (String) An optional params string or URL containing query string\n
+  //    params to be parsed. If url is omitted, the current window.location\n
+  //    is used.\n
+  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and\n
+  //    undefined to their actual value. Defaults to false if omitted.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (Object) An object representing the deserialized params string.\n
+  \n
+  // Method: jQuery.deparam.fragment\n
+  // \n
+  // Parse the fragment (hash) from a URL or the current window.location,\n
+  // deserializing it into an object, optionally coercing numbers, booleans,\n
+  // null and undefined values.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.deparam.fragment( [ url ] [, coerce ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  url - (String) An optional params string or URL containing fragment (hash)\n
+  //    params to be parsed. If url is omitted, the current window.location\n
+  //    is used.\n
+  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and\n
+  //    undefined to their actual value. Defaults to false if omitted.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (Object) An object representing the deserialized params string.\n
+  \n
+  function jq_deparam_sub( is_fragment, url_or_params, coerce ) {\n
+    if ( url_or_params === undefined || typeof url_or_params === \'boolean\' ) {\n
+      // url_or_params not specified.\n
+      coerce = url_or_params;\n
+      url_or_params = jq_param[ is_fragment ? str_fragment : str_querystring ]();\n
+    } else {\n
+      url_or_params = is_string( url_or_params )\n
+        ? url_or_params.replace( is_fragment ? re_trim_fragment : re_trim_querystring, \'\' )\n
+        : url_or_params;\n
+    }\n
+    \n
+    return jq_deparam( url_or_params, coerce );\n
+  };\n
+  \n
+  jq_deparam[ str_querystring ]                    = curry( jq_deparam_sub, 0 );\n
+  jq_deparam[ str_fragment ] = jq_deparam_fragment = curry( jq_deparam_sub, 1 );\n
+  \n
+  // Section: Element manipulation\n
+  // \n
+  // Method: jQuery.elemUrlAttr\n
+  // \n
+  // Get the internal "Default URL attribute per tag" list, or augment the list\n
+  // with additional tag-attribute pairs, in case the defaults are insufficient.\n
+  // \n
+  // In the <jQuery.fn.querystring> and <jQuery.fn.fragment> methods, this list\n
+  // is used to determine which attribute contains the URL to be modified, if\n
+  // an "attr" param is not specified.\n
+  // \n
+  // Default Tag-Attribute List:\n
+  // \n
+  //  a      - href\n
+  //  base   - href\n
+  //  iframe - src\n
+  //  img    - src\n
+  //  input  - src\n
+  //  form   - action\n
+  //  link   - href\n
+  //  script - src\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.elemUrlAttr( [ tag_attr ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  tag_attr - (Object) An object containing a list of tag names and their\n
+  //    associated default attribute names in the format { tag: \'attr\', ... } to\n
+  //    be merged into the internal tag-attribute list.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (Object) An object containing all stored tag-attribute values.\n
+  \n
+  // Only define function and set defaults if function doesn\'t already exist, as\n
+  // the urlInternal plugin will provide this method as well.\n
+  $[ str_elemUrlAttr ] || ($[ str_elemUrlAttr ] = function( obj ) {\n
+    return $.extend( elemUrlAttr_cache, obj );\n
+  })({\n
+    a: str_href,\n
+    base: str_href,\n
+    iframe: str_src,\n
+    img: str_src,\n
+    input: str_src,\n
+    form: \'action\',\n
+    link: str_href,\n
+    script: str_src\n
+  });\n
+  \n
+  jq_elemUrlAttr = $[ str_elemUrlAttr ];\n
+  \n
+  // Method: jQuery.fn.querystring\n
+  // \n
+  // Update URL attribute in one or more elements, merging the current URL (with\n
+  // or without pre-existing query string params) plus any params object or\n
+  // string into a new URL, which is then set into that attribute. Like\n
+  // <jQuery.param.querystring (build url)>, but for all elements in a jQuery\n
+  // collection.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery(\'selector\').querystring( [ attr, ] params [, merge_mode ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  attr - (String) Optional name of an attribute that will contain a URL to\n
+  //    merge params or url into. See <jQuery.elemUrlAttr> for a list of default\n
+  //    attributes.\n
+  //  params - (Object) A params object to be merged into the URL attribute.\n
+  //  params - (String) A URL containing query string params, or params string\n
+  //    to be merged into the URL attribute.\n
+  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not\n
+  //    specified, and is as-follows:\n
+  //    \n
+  //    * 0: params in the params argument will override any params in attr URL.\n
+  //    * 1: any params in attr URL will override params in the params argument.\n
+  //    * 2: params argument will completely replace any query string in attr\n
+  //         URL.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (jQuery) The initial jQuery collection of elements, but with modified URL\n
+  //  attribute values.\n
+  \n
+  // Method: jQuery.fn.fragment\n
+  // \n
+  // Update URL attribute in one or more elements, merging the current URL (with\n
+  // or without pre-existing fragment/hash params) plus any params object or\n
+  // string into a new URL, which is then set into that attribute. Like\n
+  // <jQuery.param.fragment (build url)>, but for all elements in a jQuery\n
+  // collection.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery(\'selector\').fragment( [ attr, ] params [, merge_mode ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  attr - (String) Optional name of an attribute that will contain a URL to\n
+  //    merge params into. See <jQuery.elemUrlAttr> for a list of default\n
+  //    attributes.\n
+  //  params - (Object) A params object to be merged into the URL attribute.\n
+  //  params - (String) A URL containing fragment (hash) params, or params\n
+  //    string to be merged into the URL attribute.\n
+  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not\n
+  //    specified, and is as-follows:\n
+  //    \n
+  //    * 0: params in the params argument will override any params in attr URL.\n
+  //    * 1: any params in attr URL will override params in the params argument.\n
+  //    * 2: params argument will completely replace any fragment (hash) in attr\n
+  //         URL.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (jQuery) The initial jQuery collection of elements, but with modified URL\n
+  //  attribute values.\n
+  \n
+  function jq_fn_sub( mode, force_attr, params, merge_mode ) {\n
+    if ( !is_string( params ) && typeof params !== \'object\' ) {\n
+      // force_attr not specified.\n
+      merge_mode = params;\n
+      params = force_attr;\n
+      force_attr = undefined;\n
+    }\n
+    \n
+    return this.each(function(){\n
+      var that = $(this),\n
+        \n
+        // Get attribute specified, or default specified via $.elemUrlAttr.\n
+        attr = force_attr || jq_elemUrlAttr()[ ( this.nodeName || \'\' ).toLowerCase() ] || \'\',\n
+        \n
+        // Get URL value.\n
+        url = attr && that.attr( attr ) || \'\';\n
+      \n
+      // Update attribute with new URL.\n
+      that.attr( attr, jq_param[ mode ]( url, params, merge_mode ) );\n
+    });\n
+    \n
+  };\n
+  \n
+  $.fn[ str_querystring ] = curry( jq_fn_sub, str_querystring );\n
+  $.fn[ str_fragment ]    = curry( jq_fn_sub, str_fragment );\n
+  \n
+  // Section: History, hashchange event\n
+  // \n
+  // Method: jQuery.bbq.pushState\n
+  // \n
+  // Adds a \'state\' into the browser history at the current position, setting\n
+  // location.hash and triggering any bound <hashchange event> callbacks\n
+  // (provided the new state is different than the previous state).\n
+  // \n
+  // If no arguments are passed, an empty state is created, which is just a\n
+  // shortcut for jQuery.bbq.pushState( {}, 2 ).\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.bbq.pushState( [ params [, merge_mode ] ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  params - (String) A serialized params string or a hash string beginning\n
+  //    with # to merge into location.hash.\n
+  //  params - (Object) A params object to merge into location.hash.\n
+  //  merge_mode - (Number) Merge behavior defaults to 0 if merge_mode is not\n
+  //    specified (unless a hash string beginning with # is specified, in which\n
+  //    case merge behavior defaults to 2), and is as-follows:\n
+  // \n
+  //    * 0: params in the params argument will override any params in the\n
+  //         current state.\n
+  //    * 1: any params in the current state will override params in the params\n
+  //         argument.\n
+  //    * 2: params argument will completely replace current state.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  Nothing.\n
+  // \n
+  // Additional Notes:\n
+  // \n
+  //  * Setting an empty state may cause the browser to scroll.\n
+  //  * Unlike the fragment and querystring methods, if a hash string beginning\n
+  //    with # is specified as the params agrument, merge_mode defaults to 2.\n
+  \n
+  jq_bbq.pushState = jq_bbq_pushState = function( params, merge_mode ) {\n
+    if ( is_string( params ) && /^#/.test( params ) && merge_mode === undefined ) {\n
+      // Params string begins with # and merge_mode not specified, so completely\n
+      // overwrite window.location.hash.\n
+      merge_mode = 2;\n
+    }\n
+    \n
+    var has_args = params !== undefined,\n
+      // Merge params into window.location using $.param.fragment.\n
+      url = jq_param_fragment( window[ str_location ][ str_href ],\n
+        has_args ? params : {}, has_args ? merge_mode : 2 );\n
+    \n
+    // Set new window.location.href. If hash is empty, use just # to prevent\n
+    // browser from reloading the page. Note that Safari 3 & Chrome barf on\n
+    // location.hash = \'#\'.\n
+    window[ str_location ][ str_href ] = url + ( /#/.test( url ) ? \'\' : \'#\' );\n
+  };\n
+  \n
+  // Method: jQuery.bbq.getState\n
+  // \n
+  // Retrieves the current \'state\' from the browser history, parsing\n
+  // location.hash for a specific key or returning an object containing the\n
+  // entire state, optionally coercing numbers, booleans, null and undefined\n
+  // values.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.bbq.getState( [ key ] [, coerce ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  key - (String) An optional state key for which to return a value.\n
+  //  coerce - (Boolean) If true, coerces any numbers or true, false, null, and\n
+  //    undefined to their actual value. Defaults to false.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  (Anything) If key is passed, returns the value corresponding with that key\n
+  //    in the location.hash \'state\', or undefined. If not, an object\n
+  //    representing the entire \'state\' is returned.\n
+  \n
+  jq_bbq.getState = jq_bbq_getState = function( key, coerce ) {\n
+    return key === undefined || typeof key === \'boolean\'\n
+      ? jq_deparam_fragment( key ) // \'key\' really means \'coerce\' here\n
+      : jq_deparam_fragment( coerce )[ key ];\n
+  };\n
+  \n
+  // Method: jQuery.bbq.removeState\n
+  // \n
+  // Remove one or more keys from the current browser history \'state\', creating\n
+  // a new state, setting location.hash and triggering any bound\n
+  // <hashchange event> callbacks (provided the new state is different than\n
+  // the previous state).\n
+  // \n
+  // If no arguments are passed, an empty state is created, which is just a\n
+  // shortcut for jQuery.bbq.pushState( {}, 2 ).\n
+  // \n
+  // Usage:\n
+  // \n
+  // > jQuery.bbq.removeState( [ key [, key ... ] ] );\n
+  // \n
+  // Arguments:\n
+  // \n
+  //  key - (String) One or more key values to remove from the current state,\n
+  //    passed as individual arguments.\n
+  //  key - (Array) A single array argument that contains a list of key values\n
+  //    to remove from the current state.\n
+  // \n
+  // Returns:\n
+  // \n
+  //  Nothing.\n
+  // \n
+  // Additional Notes:\n
+  // \n
+  //  * Setting an empty state may cause the browser to scroll.\n
+  \n
+  jq_bbq.removeState = function( arr ) {\n
+    var state = {};\n
+    \n
+    // If one or more arguments is passed..\n
+    if ( arr !== undefined ) {\n
+      \n
+      // Get the current state.\n
+      state = jq_bbq_getState();\n
+      \n
+      // For each passed key, delete the corresponding property from the current\n
+      // state.\n
+      $.each( $.isArray( arr ) ? arr : arguments, function(i,v){\n
+        delete state[ v ];\n
+      });\n
+    }\n
+    \n
+    // Set the state, completely overriding any existing state.\n
+    jq_bbq_pushState( state, 2 );\n
+  };\n
+  \n
+  // Event: hashchange event (BBQ)\n
+  // \n
+  // Usage in jQuery 1.4 and newer:\n
+  // \n
+  // In jQuery 1.4 and newer, the event object passed into any hashchange event\n
+  // callback is augmented with a copy of the location.hash fragment at the time\n
+  // the event was triggered as its event.fragment property. In addition, the\n
+  // event.getState method operates on this property (instead of location.hash)\n
+  // which allows this fragment-as-a-state to be referenced later, even after\n
+  // window.location may have changed.\n
+  // \n
+  // Note that event.fragment and event.getState are not defined according to\n
+  // W3C (or any other) specification, but will still be available whether or\n
+  // not the hashchange event exists natively in the browser, because of the\n
+  // utility they provide.\n
+  // \n
+  // The event.fragment property contains the output of <jQuery.param.fragment>\n
+  // and the event.getState method is equivalent to the <jQuery.bbq.getState>\n
+  // method.\n
+  // \n
+  // > $(window).bind( \'hashchange\', function( event ) {\n
+  // >   var hash_str = event.fragment,\n
+  // >     param_obj = event.getState(),\n
+  // >     param_val = event.getState( \'param_name\' ),\n
+  // >     param_val_coerced = event.getState( \'param_name\', true );\n
+  // >   ...\n
+  // > });\n
+  // \n
+  // Usage in jQuery 1.3.2:\n
+  // \n
+  // In jQuery 1.3.2, the event object cannot to be augmented as in jQuery 1.4+,\n
+  // so the fragment state isn\'t bound to the event object and must instead be\n
+  // parsed using the <jQuery.param.fragment> and <jQuery.bbq.getState> methods.\n
+  // \n
+  // > $(window).bind( \'hashchange\', function( event ) {\n
+  // >   var hash_str = $.param.fragment(),\n
+  // >     param_obj = $.bbq.getState(),\n
+  // >     param_val = $.bbq.getState( \'param_name\' ),\n
+  // >     param_val_coerced = $.bbq.getState( \'param_name\', true );\n
+  // >   ...\n
+  // > });\n
+  // \n
+  // Additional Notes:\n
+  // \n
+  // * Due to changes in the special events API, jQuery BBQ v1.2 or newer is\n
+  //   required to enable the augmented event object in jQuery 1.4.2 and newer.\n
+  // * See <jQuery hashchange event> for more detailed information.\n
+  \n
+  jq_event_special[ str_hashchange ] = $.extend( jq_event_special[ str_hashchange ], {\n
+    \n
+    // Augmenting the event object with the .fragment property and .getState\n
+    // method requires jQuery 1.4 or newer. Note: with 1.3.2, everything will\n
+    // work, but the event won\'t be augmented)\n
+    add: function( handleObj ) {\n
+      var old_handler;\n
+      \n
+      function new_handler(e) {\n
+        // e.fragment is set to the value of location.hash (with any leading #\n
+        // removed) at the time the event is triggered.\n
+        var hash = e[ str_fragment ] = jq_param_fragment();\n
+        \n
+        // e.getState() works just like $.bbq.getState(), but uses the\n
+        // e.fragment property stored on the event object.\n
+        e.getState = function( key, coerce ) {\n
+          return key === undefined || typeof key === \'boolean\'\n
+            ? jq_deparam( hash, key ) // \'key\' really means \'coerce\' here\n
+            : jq_deparam( hash, coerce )[ key ];\n
+        };\n
+        \n
+        old_handler.apply( this, arguments );\n
+      };\n
+      \n
+      // This may seem a little complicated, but it normalizes the special event\n
+      // .add method between jQuery 1.4/1.4.1 and 1.4.2+\n
+      if ( $.isFunction( handleObj ) ) {\n
+        // 1.4, 1.4.1\n
+        old_handler = handleObj;\n
+        return new_handler;\n
+      } else {\n
+        // 1.4.2+\n
+        old_handler = handleObj.handler;\n
+        handleObj.handler = new_handler;\n
+      }\n
+    }\n
+    \n
+  });\n
+  \n
+})(jQuery,this);\n
+\n
+/*!\n
+ * jQuery hashchange event - v1.2 - 2/11/2010\n
+ * http://benalman.com/projects/jquery-hashchange-plugin/\n
+ * \n
+ * Copyright (c) 2010 "Cowboy" Ben Alman\n
+ * Dual licensed under the MIT and GPL licenses.\n
+ * http://benalman.com/about/license/\n
+ */\n
+\n
+// Script: jQuery hashchange event\n
+//\n
+// *Version: 1.2, Last updated: 2/11/2010*\n
+// \n
+// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/\n
+// GitHub       - http://github.com/cowboy/jquery-hashchange/\n
+// Source       - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js\n
+// (Minified)   - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (1.1kb)\n
+// \n
+// About: License\n
+// \n
+// Copyright (c) 2010 "Cowboy" Ben Alman,\n
+// Dual licensed under the MIT and GPL licenses.\n
+// http://benalman.com/about/license/\n
+// \n
+// About: Examples\n
+// \n
+// This working example, complete with fully commented code, illustrate one way\n
+// in which this plugin can be used.\n
+// \n
+// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/\n
+// \n
+// About: Support and Testing\n
+// \n
+// Information about what version or versions of jQuery this plugin has been\n
+// tested with, what browsers it has been tested in, and where the unit tests\n
+// reside (so you can test it yourself).\n
+// \n
+// jQuery Versions - 1.3.2, 1.4.1, 1.4.2\n
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome, Opera 9.6-10.1.\n
+// Unit Tests      - http://benalman.com/code/projects/jquery-hashchange/unit/\n
+// \n
+// About: Known issues\n
+// \n
+// While this jQuery hashchange event implementation is quite stable and robust,\n
+// there are a few unfortunate browser bugs surrounding expected hashchange\n
+// event-based behaviors, independent of any JavaScript window.onhashchange\n
+// abstraction. See the following examples for more information:\n
+// \n
+// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/\n
+// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/\n
+// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/\n
+// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/\n
+// \n
+// About: Release History\n
+// \n
+// 1.2   - (2/11/2010) Fixed a bug where coming back to a page using this plugin\n
+//         from a page on another domain would cause an error in Safari 4. Also,\n
+//         IE6/7 Iframe is now inserted after the body (this actually works),\n
+//         which prevents the page from scrolling when the event is first bound.\n
+//         Event can also now be bound before DOM ready, but it won\'t be usable\n
+//         before then in IE6/7.\n
+// 1.1   - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug\n
+//         where browser version is incorrectly reported as 8.0, despite\n
+//         inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.\n
+// 1.0   - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special\n
+//         window.onhashchange functionality into a separate plugin for users\n
+//         who want just the basic event & back button support, without all the\n
+//         extra awesomeness that BBQ provides. This plugin will be included as\n
+//         part of jQuery BBQ, but also be available separately.\n
+\n
+(function($,window,undefined){\n
+  \'$:nomunge\'; // Used by YUI compressor.\n
+  \n
+  // Method / object references.\n
+  var fake_onhashchange,\n
+    jq_event_special = $.event.special,\n
+    \n
+    // Reused strings.\n
+    str_location = \'location\',\n
+    str_hashchange = \'hashchange\',\n
+    str_href = \'href\',\n
+    \n
+    // IE6/7 specifically need some special love when it comes to back-button\n
+    // support, so let\'s do a little browser sniffing..\n
+    browser = $.browser,\n
+    mode = document.documentMode,\n
+    is_old_ie = browser.msie && ( mode === undefined || mode < 8 ),\n
+    \n
+    // Does the browser support window.onhashchange? Test for IE version, since\n
+    // IE8 incorrectly reports this when in "IE7" or "IE8 Compatibility View"!\n
+    supports_onhashchange = \'on\' + str_hashchange in window && !is_old_ie;\n
+  \n
+  // Get location.hash (or what you\'d expect location.hash to be) sans any\n
+  // leading #. Thanks for making this necessary, Firefox!\n
+  function get_fragment( url ) {\n
+    url = url || window[ str_location ][ str_href ];\n
+    return url.replace( /^[^#]*#?(.*)$/, \'$1\' );\n
+  };\n
+  \n
+  // Property: jQuery.hashchangeDelay\n
+  // \n
+  // The numeric interval (in milliseconds) at which the <hashchange event>\n
+  // polling loop executes. Defaults to 100.\n
+  \n
+  $[ str_hashchange + \'Delay\' ] = 100;\n
+  \n
+  // Event: hashchange event\n
+  // \n
+  // Fired when location.hash changes. In browsers that support it, the native\n
+  // window.onhashchange event is used (IE8, FF3.6), otherwise a polling loop is\n
+  // initialized, running every <jQuery.hashchangeDelay> milliseconds to see if\n
+  // the hash has changed. In IE 6 and 7, a hidden Iframe is created to allow\n
+  // the back button and hash-based history to work.\n
+  // \n
+  // Usage:\n
+  // \n
+  // > $(window).bind( \'hashchange\', function(e) {\n
+  // >   var hash = location.hash;\n
+  // >   ...\n
+  // > });\n
+  // \n
+  // Additional Notes:\n
+  // \n
+  // * The polling loop and Iframe are not created until at least one callback\n
+  //   is actually bound to \'hashchange\'.\n
+  // * If you need the bound callback(s) to execute immediately, in cases where\n
+  //   the page \'state\' exists on page load (via bookmark or page refresh, for\n
+  //   example) use $(window).trigger( \'hashchange\' );\n
+  // * The event can be bound before DOM ready, but since it won\'t be usable\n
+  //   before then in IE6/7 (due to the necessary Iframe), recommended usage is\n
+  //   to bind it inside a $(document).ready() callback.\n
+  \n
+  jq_event_special[ str_hashchange ] = $.extend( jq_event_special[ str_hashchange ], {\n
+    \n
+    // Called only when the first \'hashchange\' event is bound to window.\n
+    setup: function() {\n
+      // If window.onhashchange is supported natively, there\'s nothing to do..\n
+      if ( supports_onhashchange ) { return false; }\n
+      \n
+      // Otherwise, we need to create our own. And we don\'t want to call this\n
+      // until the user binds to the event, just in case they never do, since it\n
+      // will create a polling loop and possibly even a hidden Iframe.\n
+      $( fake_onhashchange.start );\n
+    },\n
+    \n
+    // Called only when the last \'hashchange\' event is unbound from window.\n
+    teardown: function() {\n
+      // If window.onhashchange is supported natively, there\'s nothing to do..\n
+      if ( supports_onhashchange ) { return false; }\n
+      \n
+      // Otherwise, we need to stop ours (if possible).\n
+      $( fake_onhashchange.stop );\n
+    }\n
+    \n
+  });\n
+  \n
+  // fake_onhashchange does all the work of triggering the window.onhashchange\n
+  // event for browsers that don\'t natively support it, including creating a\n
+  // polling loop to watch for hash changes and in IE 6/7 creating a hidden\n
+  // Iframe to enable back and forward.\n
+  fake_onhashchange = (function(){\n
+    var self = {},\n
+      timeout_id,\n
+      iframe,\n
+      set_history,\n
+      get_history;\n
+    \n
+    // Initialize. In IE 6/7, creates a hidden Iframe for history handling.\n
+    function init(){\n
+      // Most browsers don\'t need special methods here..\n
+      set_history = get_history = function(val){ return val; };\n
+      \n
+      // But IE6/7 do!\n
+      if ( is_old_ie ) {\n
+        \n
+        // Create hidden Iframe after the end of the body to prevent initial\n
+        // page load from scrolling unnecessarily.\n
+        iframe = $(\'<iframe src="javascript:0"/>\').hide().insertAfter( \'body\' )[0].contentWindow;\n
+        \n
+        // Get history by looking at the hidden Iframe\'s location.hash.\n
+        get_history = function() {\n
+          return get_fragment( iframe.document[ str_location ][ str_href ] );\n
+        };\n
+        \n
+        // Set a new history item by opening and then closing the Iframe\n
+        // document, *then* setting its location.hash.\n
+        set_history = function( hash, history_hash ) {\n
+          if ( hash !== history_hash ) {\n
+            var doc = iframe.document;\n
+            doc.open().close();\n
+            doc[ str_location ].hash = \'#\' + hash;\n
+          }\n
+        };\n
+        \n
+        // Set initial history.\n
+        set_history( get_fragment() );\n
+      }\n
+    };\n
+    \n
+    // Start the polling loop.\n
+    self.start = function() {\n
+      // Polling loop is already running!\n
+      if ( timeout_id ) { return; }\n
+      \n
+      // Remember the initial hash so it doesn\'t get triggered immediately.\n
+      var last_hash = get_fragment();\n
+      \n
+      // Initialize if not yet initialized.\n
+      set_history || init();\n
+      \n
+      // This polling loop checks every $.hashchangeDelay milliseconds to see if\n
+      // location.hash has changed, and triggers the \'hashchange\' event on\n
+      // window when necessary.\n
+      (function loopy(){\n
+        var hash = get_fragment(),\n
+          history_hash = get_history( last_hash );\n
+        \n
+        if ( hash !== last_hash ) {\n
+          set_history( last_hash = hash, history_hash );\n
+          \n
+          $(window).trigger( str_hashchange );\n
+          \n
+        } else if ( history_hash !== last_hash ) {\n
+          window[ str_location ][ str_href ] = window[ str_location ][ str_href ].replace( /#.*/, \'\' ) + \'#\' + history_hash;\n
+        }\n
+        \n
+        timeout_id = setTimeout( loopy, $[ str_hashchange + \'Delay\' ] );\n
+      })();\n
+    };\n
+    \n
+    // Stop the polling loop, but only if an IE6/7 Iframe wasn\'t created. In\n
+    // that case, even if there are no longer any bound event handlers, the\n
+    // polling loop is still necessary for back/next to work at all!\n
+    self.stop = function() {\n
+      if ( !iframe ) {\n
+        timeout_id && clearTimeout( timeout_id );\n
+        timeout_id = 0;\n
+      }\n
+    };\n
+    \n
+    return self;\n
+  })();\n
+  \n
+})(jQuery,this);\n
+\n
+
+
+]]></string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>size</string> </key>
+            <value> <int>43249</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>bbq.js</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/change_log b/bt5/erp5_jquery_plugin_bbq/bt/change_log
new file mode 100644
index 0000000000..e1d0b8a2b6
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/change_log
@@ -0,0 +1,2 @@
+2012-12-14 lingnan
+* Initial commit
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/copyright_list b/bt5/erp5_jquery_plugin_bbq/bt/copyright_list
new file mode 100644
index 0000000000..f9342e8df2
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/copyright_list
@@ -0,0 +1 @@
+2012 (c) Nexedi SA
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/dependency_list b/bt5/erp5_jquery_plugin_bbq/bt/dependency_list
new file mode 100644
index 0000000000..a3d3a39331
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/dependency_list
@@ -0,0 +1 @@
+erp5_jquery
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/description b/bt5/erp5_jquery_plugin_bbq/bt/description
new file mode 100644
index 0000000000..358397763a
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/description
@@ -0,0 +1,2 @@
+This  Business Template contains only static files of bbq library 1.2.1.
+* https://github.com/cowboy/jquery-bbq/
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/license b/bt5/erp5_jquery_plugin_bbq/bt/license
new file mode 100644
index 0000000000..e6816b9c6b
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/license
@@ -0,0 +1 @@
+MIT/GPL
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/maintainer_list b/bt5/erp5_jquery_plugin_bbq/bt/maintainer_list
new file mode 100644
index 0000000000..23166f16ce
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/maintainer_list
@@ -0,0 +1 @@
+lingnan
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/revision b/bt5/erp5_jquery_plugin_bbq/bt/revision
new file mode 100644
index 0000000000..bf0d87ab1b
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/revision
@@ -0,0 +1 @@
+4
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/template_format_version b/bt5/erp5_jquery_plugin_bbq/bt/template_format_version
new file mode 100644
index 0000000000..56a6051ca2
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/template_path_list b/bt5/erp5_jquery_plugin_bbq/bt/template_path_list
new file mode 100644
index 0000000000..f165a875a8
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/template_path_list
@@ -0,0 +1,2 @@
+portal_skins/erp5_jquery/jquery/plugin/bbq
+portal_skins/erp5_jquery/jquery/plugin/bbq/**
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/title b/bt5/erp5_jquery_plugin_bbq/bt/title
new file mode 100644
index 0000000000..68dd9a67c5
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/title
@@ -0,0 +1 @@
+erp5_jquery_plugin_bbq
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_bbq/bt/version b/bt5/erp5_jquery_plugin_bbq/bt/version
new file mode 100644
index 0000000000..48360de846
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_bbq/bt/version
@@ -0,0 +1 @@
+5.4.7
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin.xml b/bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin.xml
new file mode 100644
index 0000000000..0b36d39007
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Folder" module="OFS.Folder"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>formplugin</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin/formplugin.js.xml b/bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin/formplugin.js.xml
new file mode 100644
index 0000000000..1325fb37f1
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formplugin/formplugin.js.xml
@@ -0,0 +1,719 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_EtagSupport__etag</string> </key>
+            <value> <string>ts54097163.47</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>formplugin.js</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>application/javascript</string> </value>
+        </item>
+        <item>
+            <key> <string>data</string> </key>
+            <value> <string encoding="cdata"><![CDATA[
+
+/*!\n
+ * jQuery Form Plugin\n
+ * version: 2.43 (12-MAR-2010)\n
+ * @requires jQuery v1.3.2 or later\n
+ *\n
+ * Examples and documentation at: http://malsup.com/jquery/form/\n
+ * Dual licensed under the MIT and GPL licenses:\n
+ *   http://www.opensource.org/licenses/mit-license.php\n
+ *   http://www.gnu.org/licenses/gpl.html\n
+ */\n
+;(function($) {\n
+\n
+/*\n
+\tUsage Note:\n
+\t-----------\n
+\tDo not use both ajaxSubmit and ajaxForm on the same form.  These\n
+\tfunctions are intended to be exclusive.  Use ajaxSubmit if you want\n
+\tto bind your own submit handler to the form.  For example,\n
+\n
+\t$(document).ready(function() {\n
+\t\t$(\'#myForm\').bind(\'submit\', function() {\n
+\t\t\t$(this).ajaxSubmit({\n
+\t\t\t\ttarget: \'#output\'\n
+\t\t\t});\n
+\t\t\treturn false; // <-- important!\n
+\t\t});\n
+\t});\n
+\n
+\tUse ajaxForm when you want the plugin to manage all the event binding\n
+\tfor you.  For example,\n
+\n
+\t$(document).ready(function() {\n
+\t\t$(\'#myForm\').ajaxForm({\n
+\t\t\ttarget: \'#output\'\n
+\t\t});\n
+\t});\n
+\n
+\tWhen using ajaxForm, the ajaxSubmit function will be invoked for you\n
+\tat the appropriate time.\n
+*/\n
+\n
+/**\n
+ * ajaxSubmit() provides a mechanism for immediately submitting\n
+ * an HTML form using AJAX.\n
+ */\n
+$.fn.ajaxSubmit = function(options) {\n
+\t// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)\n
+\tif (!this.length) {\n
+\t\tlog(\'ajaxSubmit: skipping submit process - no element selected\');\n
+\t\treturn this;\n
+\t}\n
+\n
+\tif (typeof options == \'function\')\n
+\t\toptions = { success: options };\n
+\n
+\tvar url = $.trim(this.attr(\'action\'));\n
+\tif (url) {\n
+\t\t// clean url (don\'t include hash vaue)\n
+\t\turl = (url.match(/^([^#]+)/)||[])[1];\n
+   \t}\n
+   \turl = url || window.location.href || \'\';\n
+\n
+\toptions = $.extend({\n
+\t\turl:  url,\n
+\t\ttype: this.attr(\'method\') || \'GET\',\n
+\t\tiframeSrc: /^https/i.test(window.location.href || \'\') ? \'javascript:false\' : \'about:blank\'\n
+\t}, options || {});\n
+\n
+\t// hook for manipulating the form data before it is extracted;\n
+\t// convenient for use with rich editors like tinyMCE or FCKEditor\n
+\tvar veto = {};\n
+\tthis.trigger(\'form-pre-serialize\', [this, options, veto]);\n
+\tif (veto.veto) {\n
+\t\tlog(\'ajaxSubmit: submit vetoed via form-pre-serialize trigger\');\n
+\t\treturn this;\n
+\t}\n
+\n
+\t// provide opportunity to alter form data before it is serialized\n
+\tif (options.beforeSerialize && options.beforeSerialize(this, options) === false) {\n
+\t\tlog(\'ajaxSubmit: submit aborted via beforeSerialize callback\');\n
+\t\treturn this;\n
+\t}\n
+\n
+\tvar a = this.formToArray(options.semantic);\n
+\tif (options.data) {\n
+\t\toptions.extraData = options.data;\n
+\t\tfor (var n in options.data) {\n
+\t\t  if(options.data[n] instanceof Array) {\n
+\t\t\tfor (var k in options.data[n])\n
+\t\t\t  a.push( { name: n, value: options.data[n][k] } );\n
+\t\t  }\n
+\t\t  else\n
+\t\t\t a.push( { name: n, value: options.data[n] } );\n
+\t\t}\n
+\t}\n
+\n
+\t// give pre-submit callback an opportunity to abort the submit\n
+\tif (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {\n
+\t\tlog(\'ajaxSubmit: submit aborted via beforeSubmit callback\');\n
+\t\treturn this;\n
+\t}\n
+\n
+\t// fire vetoable \'validate\' event\n
+\tthis.trigger(\'form-submit-validate\', [a, this, options, veto]);\n
+\tif (veto.veto) {\n
+\t\tlog(\'ajaxSubmit: submit vetoed via form-submit-validate trigger\');\n
+\t\treturn this;\n
+\t}\n
+\n
+\tvar q = $.param(a);\n
+\n
+\tif (options.type.toUpperCase() == \'GET\') {\n
+\t\toptions.url += (options.url.indexOf(\'?\') >= 0 ? \'&\' : \'?\') + q;\n
+\t\toptions.data = null;  // data is null for \'get\'\n
+\t}\n
+\telse\n
+\t\toptions.data = q; // data is the query string for \'post\'\n
+\n
+\tvar $form = this, callbacks = [];\n
+\tif (options.resetForm) callbacks.push(function() { $form.resetForm(); });\n
+\tif (options.clearForm) callbacks.push(function() { $form.clearForm(); });\n
+\n
+\t// perform a load on the target only if dataType is not provided\n
+\tif (!options.dataType && options.target) {\n
+\t\tvar oldSuccess = options.success || function(){};\n
+\t\tcallbacks.push(function(data) {\n
+\t\t\tvar fn = options.replaceTarget ? \'replaceWith\' : \'html\';\n
+\t\t\t$(options.target)[fn](data).each(oldSuccess, arguments);\n
+\t\t});\n
+\t}\n
+\telse if (options.success)\n
+\t\tcallbacks.push(options.success);\n
+\n
+\toptions.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg\n
+\t\tfor (var i=0, max=callbacks.length; i < max; i++)\n
+\t\t\tcallbacks[i].apply(options, [data, status, xhr || $form, $form]);\n
+\t};\n
+\n
+\t// are there files to upload?\n
+\tvar files = $(\'input:file\', this).fieldValue();\n
+\tvar found = false;\n
+\tfor (var j=0; j < files.length; j++)\n
+\t\tif (files[j])\n
+\t\t\tfound = true;\n
+\n
+\tvar multipart = false;\n
+//\tvar mp = \'multipart/form-data\';\n
+//\tmultipart = ($form.attr(\'enctype\') == mp || $form.attr(\'encoding\') == mp);\n
+\n
+\t// options.iframe allows user to force iframe mode\n
+\t// 06-NOV-09: now defaulting to iframe mode if file input is detected\n
+   if ((files.length && options.iframe !== false) || options.iframe || found || multipart) {\n
+\t   // hack to fix Safari hang (thanks to Tim Molendijk for this)\n
+\t   // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d\n
+\t   if (options.closeKeepAlive)\n
+\t\t   $.get(options.closeKeepAlive, fileUpload);\n
+\t   else\n
+\t\t   fileUpload();\n
+\t   }\n
+   else\n
+\t   $.ajax(options);\n
+\n
+\t// fire \'notify\' event\n
+\tthis.trigger(\'form-submit-notify\', [this, options]);\n
+\treturn this;\n
+\n
+\n
+\t// private function for handling file uploads (hat tip to YAHOO!)\n
+\tfunction fileUpload() {\n
+\t\tvar form = $form[0];\n
+\n
+\t\tif ($(\':input[name=submit]\', form).length) {\n
+\t\t\talert(\'Error: Form elements must not be named "submit".\');\n
+\t\t\treturn;\n
+\t\t}\n
+\n
+\t\tvar opts = $.extend({}, $.ajaxSettings, options);\n
+\t\tvar s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);\n
+\n
+\t\tvar id = \'jqFormIO\' + (new Date().getTime());\n
+\t\tvar $io = $(\'<iframe id="\' + id + \'" name="\' + id + \'" src="\'+ opts.iframeSrc +\'" onload="(jQuery(this).data(\\\'form-plugin-onload\\\'))()" />\');\n
+\t\tvar io = $io[0];\n
+\n
+\t\t$io.css({ position: \'absolute\', top: \'-1000px\', left: \'-1000px\' });\n
+\n
+\t\tvar xhr = { // mock object\n
+\t\t\taborted: 0,\n
+\t\t\tresponseText: null,\n
+\t\t\tresponseXML: null,\n
+\t\t\tstatus: 0,\n
+\t\t\tstatusText: \'n/a\',\n
+\t\t\tgetAllResponseHeaders: function() {},\n
+\t\t\tgetResponseHeader: function() {},\n
+\t\t\tsetRequestHeader: function() {},\n
+\t\t\tabort: function() {\n
+\t\t\t\tthis.aborted = 1;\n
+\t\t\t\t$io.attr(\'src\', opts.iframeSrc); // abort op in progress\n
+\t\t\t}\n
+\t\t};\n
+\n
+\t\tvar g = opts.global;\n
+\t\t// trigger ajax global events so that activity/block indicators work like normal\n
+\t\tif (g && ! $.active++) $.event.trigger("ajaxStart");\n
+\t\tif (g) $.event.trigger("ajaxSend", [xhr, opts]);\n
+\n
+\t\tif (s.beforeSend && s.beforeSend(xhr, s) === false) {\n
+\t\t\ts.global && $.active--;\n
+\t\t\treturn;\n
+\t\t}\n
+\t\tif (xhr.aborted)\n
+\t\t\treturn;\n
+\n
+\t\tvar cbInvoked = false;\n
+\t\tvar timedOut = 0;\n
+\n
+\t\t// add submitting element to data if we know it\n
+\t\tvar sub = form.clk;\n
+\t\tif (sub) {\n
+\t\t\tvar n = sub.name;\n
+\t\t\tif (n && !sub.disabled) {\n
+\t\t\t\topts.extraData = opts.extraData || {};\n
+\t\t\t\topts.extraData[n] = sub.value;\n
+\t\t\t\tif (sub.type == "image") {\n
+\t\t\t\t\topts.extraData[n+\'.x\'] = form.clk_x;\n
+\t\t\t\t\topts.extraData[n+\'.y\'] = form.clk_y;\n
+\t\t\t\t}\n
+\t\t\t}\n
+\t\t}\n
+\n
+\t\t// take a breath so that pending repaints get some cpu time before the upload starts\n
+\t\tfunction doSubmit() {\n
+\t\t\t// make sure form attrs are set\n
+\t\t\tvar t = $form.attr(\'target\'), a = $form.attr(\'action\');\n
+\n
+\t\t\t// update form attrs in IE friendly way\n
+\t\t\tform.setAttribute(\'target\',id);\n
+\t\t\tif (form.getAttribute(\'method\') != \'POST\')\n
+\t\t\t\tform.setAttribute(\'method\', \'POST\');\n
+\t\t\tif (form.getAttribute(\'action\') != opts.url)\n
+\t\t\t\tform.setAttribute(\'action\', opts.url);\n
+\n
+\t\t\t// ie borks in some cases when setting encoding\n
+\t\t\tif (! opts.skipEncodingOverride) {\n
+\t\t\t\t$form.attr({\n
+\t\t\t\t\tencoding: \'multipart/form-data\',\n
+\t\t\t\t\tenctype:  \'multipart/form-data\'\n
+\t\t\t\t});\n
+\t\t\t}\n
+\n
+\t\t\t// support timout\n
+\t\t\tif (opts.timeout)\n
+\t\t\t\tsetTimeout(function() { timedOut = true; cb(); }, opts.timeout);\n
+\n
+\t\t\t// add "extra" data to form if provided in options\n
+\t\t\tvar extraInputs = [];\n
+\t\t\ttry {\n
+\t\t\t\tif (opts.extraData)\n
+\t\t\t\t\tfor (var n in opts.extraData)\n
+\t\t\t\t\t\textraInputs.push(\n
+\t\t\t\t\t\t\t$(\'<input type="hidden" name="\'+n+\'" value="\'+opts.extraData[n]+\'" />\')\n
+\t\t\t\t\t\t\t\t.appendTo(form)[0]);\n
+\n
+\t\t\t\t// add iframe to doc and submit the form\n
+\t\t\t\t$io.appendTo(\'body\');\n
+\t\t\t\t$io.data(\'form-plugin-onload\', cb);\n
+\t\t\t\tform.submit();\n
+\t\t\t}\n
+\t\t\tfinally {\n
+\t\t\t\t// reset attrs and remove "extra" input elements\n
+\t\t\t\tform.setAttribute(\'action\',a);\n
+\t\t\t\tt ? form.setAttribute(\'target\', t) : $form.removeAttr(\'target\');\n
+\t\t\t\t$(extraInputs).remove();\n
+\t\t\t}\n
+\t\t};\n
+\n
+\t\tif (opts.forceSync)\n
+\t\t\tdoSubmit();\n
+\t\telse\n
+\t\t\tsetTimeout(doSubmit, 10); // this lets dom updates render\n
+\t\n
+\t\tvar domCheckCount = 100;\n
+\n
+\t\tfunction cb() {\n
+\t\t\tif (cbInvoked) \n
+\t\t\t\treturn;\n
+\n
+\t\t\tvar ok = true;\n
+\t\t\ttry {\n
+\t\t\t\tif (timedOut) throw \'timeout\';\n
+\t\t\t\t// extract the server response from the iframe\n
+\t\t\t\tvar data, doc;\n
+\n
+\t\t\t\tdoc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;\n
+\t\t\t\t\n
+\t\t\t\tvar isXml = opts.dataType == \'xml\' || doc.XMLDocument || $.isXMLDoc(doc);\n
+\t\t\t\tlog(\'isXml=\'+isXml);\n
+\t\t\t\tif (!isXml && (doc.body == null || doc.body.innerHTML == \'\')) {\n
+\t\t\t\t \tif (--domCheckCount) {\n
+\t\t\t\t\t\t// in some browsers (Opera) the iframe DOM is not always traversable when\n
+\t\t\t\t\t\t// the onload callback fires, so we loop a bit to accommodate\n
+\t\t\t\t \t\tlog(\'requeing onLoad callback, DOM not available\');\n
+\t\t\t\t\t\tsetTimeout(cb, 250);\n
+\t\t\t\t\t\treturn;\n
+\t\t\t\t\t}\n
+\t\t\t\t\tlog(\'Could not access iframe DOM after 100 tries.\');\n
+\t\t\t\t\treturn;\n
+\t\t\t\t}\n
+\n
+\t\t\t\tlog(\'response detected\');\n
+\t\t\t\tcbInvoked = true;\n
+\t\t\t\txhr.responseText = doc.body ? doc.body.innerHTML : null;\n
+\t\t\t\txhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;\n
+\t\t\t\txhr.getResponseHeader = function(header){\n
+\t\t\t\t\tvar headers = {\'content-type\': opts.dataType};\n
+\t\t\t\t\treturn headers[header];\n
+\t\t\t\t};\n
+\n
+\t\t\t\tif (opts.dataType == \'json\' || opts.dataType == \'script\') {\n
+\t\t\t\t\t// see if user embedded response in textarea\n
+\t\t\t\t\tvar ta = doc.getElementsByTagName(\'textarea\')[0];\n
+\t\t\t\t\tif (ta)\n
+\t\t\t\t\t\txhr.responseText = ta.value;\n
+\t\t\t\t\telse {\n
+\t\t\t\t\t\t// account for browsers injecting pre around json response\n
+\t\t\t\t\t\tvar pre = doc.getElementsByTagName(\'pre\')[0];\n
+\t\t\t\t\t\tif (pre)\n
+\t\t\t\t\t\t\txhr.responseText = pre.innerHTML;\n
+\t\t\t\t\t}\t\t\t  \n
+\t\t\t\t}\n
+\t\t\t\telse if (opts.dataType == \'xml\' && !xhr.responseXML && xhr.responseText != null) {\n
+\t\t\t\t\txhr.responseXML = toXml(xhr.responseText);\n
+\t\t\t\t}\n
+\t\t\t\tdata = $.httpData(xhr, opts.dataType);\n
+\t\t\t}\n
+\t\t\tcatch(e){\n
+\t\t\t\tlog(\'error caught:\',e);\n
+\t\t\t\tok = false;\n
+\t\t\t\txhr.error = e;\n
+\t\t\t\t$.handleError(opts, xhr, \'error\', e);\n
+\t\t\t}\n
+\n
+\t\t\t// ordering of these callbacks/triggers is odd, but that\'s how $.ajax does it\n
+\t\t\tif (ok) {\n
+\t\t\t\topts.success(data, \'success\');\n
+\t\t\t\tif (g) $.event.trigger("ajaxSuccess", [xhr, opts]);\n
+\t\t\t}\n
+\t\t\tif (g) $.event.trigger("ajaxComplete", [xhr, opts]);\n
+\t\t\tif (g && ! --$.active) $.event.trigger("ajaxStop");\n
+\t\t\tif (opts.complete) opts.complete(xhr, ok ? \'success\' : \'error\');\n
+\n
+\t\t\t// clean up\n
+\t\t\tsetTimeout(function() {\n
+\t\t\t\t$io.removeData(\'form-plugin-onload\');\n
+\t\t\t\t$io.remove();\n
+\t\t\t\txhr.responseXML = null;\n
+\t\t\t}, 100);\n
+\t\t};\n
+\n
+\t\tfunction toXml(s, doc) {\n
+\t\t\tif (window.ActiveXObject) {\n
+\t\t\t\tdoc = new ActiveXObject(\'Microsoft.XMLDOM\');\n
+\t\t\t\tdoc.async = \'false\';\n
+\t\t\t\tdoc.loadXML(s);\n
+\t\t\t}\n
+\t\t\telse\n
+\t\t\t\tdoc = (new DOMParser()).parseFromString(s, \'text/xml\');\n
+\t\t\treturn (doc && doc.documentElement && doc.documentElement.tagName != \'parsererror\') ? doc : null;\n
+\t\t};\n
+\t};\n
+};\n
+\n
+/**\n
+ * ajaxForm() provides a mechanism for fully automating form submission.\n
+ *\n
+ * The advantages of using this method instead of ajaxSubmit() are:\n
+ *\n
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element\n
+ *\tis used to submit the form).\n
+ * 2. This method will include the submit element\'s name/value data (for the element that was\n
+ *\tused to submit the form).\n
+ * 3. This method binds the submit() method to the form for you.\n
+ *\n
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely\n
+ * passes the options argument along after properly binding events for submit elements and\n
+ * the form itself.\n
+ */\n
+$.fn.ajaxForm = function(options) {\n
+\treturn this.ajaxFormUnbind().bind(\'submit.form-plugin\', function(e) {\n
+\t\te.preventDefault();\n
+\t\t$(this).ajaxSubmit(options);\n
+\t}).bind(\'click.form-plugin\', function(e) {\n
+\t\tvar target = e.target;\n
+\t\tvar $el = $(target);\n
+\t\tif (!($el.is(":submit,input:image"))) {\n
+\t\t\t// is this a child element of the submit el?  (ex: a span within a button)\n
+\t\t\tvar t = $el.closest(\':submit\');\n
+\t\t\tif (t.length == 0)\n
+\t\t\t\treturn;\n
+\t\t\ttarget = t[0];\n
+\t\t}\n
+\t\tvar form = this;\n
+\t\tform.clk = target;\n
+\t\tif (target.type == \'image\') {\n
+\t\t\tif (e.offsetX != undefined) {\n
+\t\t\t\tform.clk_x = e.offsetX;\n
+\t\t\t\tform.clk_y = e.offsetY;\n
+\t\t\t} else if (typeof $.fn.offset == \'function\') { // try to use dimensions plugin\n
+\t\t\t\tvar offset = $el.offset();\n
+\t\t\t\tform.clk_x = e.pageX - offset.left;\n
+\t\t\t\tform.clk_y = e.pageY - offset.top;\n
+\t\t\t} else {\n
+\t\t\t\tform.clk_x = e.pageX - target.offsetLeft;\n
+\t\t\t\tform.clk_y = e.pageY - target.offsetTop;\n
+\t\t\t}\n
+\t\t}\n
+\t\t// clear form vars\n
+\t\tsetTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);\n
+\t});\n
+};\n
+\n
+// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm\n
+$.fn.ajaxFormUnbind = function() {\n
+\treturn this.unbind(\'submit.form-plugin click.form-plugin\');\n
+};\n
+\n
+/**\n
+ * formToArray() gathers form element data into an array of objects that can\n
+ * be passed to any of the following ajax functions: $.get, $.post, or load.\n
+ * Each object in the array has both a \'name\' and \'value\' property.  An example of\n
+ * an array for a simple login form might be:\n
+ *\n
+ * [ { name: \'username\', value: \'jresig\' }, { name: \'password\', value: \'secret\' } ]\n
+ *\n
+ * It is this array that is passed to pre-submit callback functions provided to the\n
+ * ajaxSubmit() and ajaxForm() methods.\n
+ */\n
+$.fn.formToArray = function(semantic) {\n
+\tvar a = [];\n
+\tif (this.length == 0) return a;\n
+\n
+\tvar form = this[0];\n
+\tvar els = semantic ? form.getElementsByTagName(\'*\') : form.elements;\n
+\tif (!els) return a;\n
+\tfor(var i=0, max=els.length; i < max; i++) {\n
+\t\tvar el = els[i];\n
+\t\tvar n = el.name;\n
+\t\tif (!n) continue;\n
+\n
+\t\tif (semantic && form.clk && el.type == "image") {\n
+\t\t\t// handle image inputs on the fly when semantic == true\n
+\t\t\tif(!el.disabled && form.clk == el) {\n
+\t\t\t\ta.push({name: n, value: $(el).val()});\n
+\t\t\t\ta.push({name: n+\'.x\', value: form.clk_x}, {name: n+\'.y\', value: form.clk_y});\n
+\t\t\t}\n
+\t\t\tcontinue;\n
+\t\t}\n
+\n
+\t\tvar v = $.fieldValue(el, true);\n
+\t\tif (v && v.constructor == Array) {\n
+\t\t\tfor(var j=0, jmax=v.length; j < jmax; j++)\n
+\t\t\t\ta.push({name: n, value: v[j]});\n
+\t\t}\n
+\t\telse if (v !== null && typeof v != \'undefined\')\n
+\t\t\ta.push({name: n, value: v});\n
+\t}\n
+\n
+\tif (!semantic && form.clk) {\n
+\t\t// input type==\'image\' are not found in elements array! handle it here\n
+\t\tvar $input = $(form.clk), input = $input[0], n = input.name;\n
+\t\tif (n && !input.disabled && input.type == \'image\') {\n
+\t\t\ta.push({name: n, value: $input.val()});\n
+\t\t\ta.push({name: n+\'.x\', value: form.clk_x}, {name: n+\'.y\', value: form.clk_y});\n
+\t\t}\n
+\t}\n
+\treturn a;\n
+};\n
+\n
+/**\n
+ * Serializes form data into a \'submittable\' string. This method will return a string\n
+ * in the format: name1=value1&amp;name2=value2\n
+ */\n
+$.fn.formSerialize = function(semantic) {\n
+\t//hand off to jQuery.param for proper encoding\n
+\treturn $.param(this.formToArray(semantic));\n
+};\n
+\n
+/**\n
+ * Serializes all field elements in the jQuery object into a query string.\n
+ * This method will return a string in the format: name1=value1&amp;name2=value2\n
+ */\n
+$.fn.fieldSerialize = function(successful) {\n
+\tvar a = [];\n
+\tthis.each(function() {\n
+\t\tvar n = this.name;\n
+\t\tif (!n) return;\n
+\t\tvar v = $.fieldValue(this, successful);\n
+\t\tif (v && v.constructor == Array) {\n
+\t\t\tfor (var i=0,max=v.length; i < max; i++)\n
+\t\t\t\ta.push({name: n, value: v[i]});\n
+\t\t}\n
+\t\telse if (v !== null && typeof v != \'undefined\')\n
+\t\t\ta.push({name: this.name, value: v});\n
+\t});\n
+\t//hand off to jQuery.param for proper encoding\n
+\treturn $.param(a);\n
+};\n
+\n
+/**\n
+ * Returns the value(s) of the element in the matched set.  For example, consider the following form:\n
+ *\n
+ *  <form><fieldset>\n
+ *\t  <input name="A" type="text" />\n
+ *\t  <input name="A" type="text" />\n
+ *\t  <input name="B" type="checkbox" value="B1" />\n
+ *\t  <input name="B" type="checkbox" value="B2"/>\n
+ *\t  <input name="C" type="radio" value="C1" />\n
+ *\t  <input name="C" type="radio" value="C2" />\n
+ *  </fieldset></form>\n
+ *\n
+ *  var v = $(\':text\').fieldValue();\n
+ *  // if no values are entered into the text inputs\n
+ *  v == [\'\',\'\']\n
+ *  // if values entered into the text inputs are \'foo\' and \'bar\'\n
+ *  v == [\'foo\',\'bar\']\n
+ *\n
+ *  var v = $(\':checkbox\').fieldValue();\n
+ *  // if neither checkbox is checked\n
+ *  v === undefined\n
+ *  // if both checkboxes are checked\n
+ *  v == [\'B1\', \'B2\']\n
+ *\n
+ *  var v = $(\':radio\').fieldValue();\n
+ *  // if neither radio is checked\n
+ *  v === undefined\n
+ *  // if first radio is checked\n
+ *  v == [\'C1\']\n
+ *\n
+ * The successful argument controls whether or not the field element must be \'successful\'\n
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).\n
+ * The default value of the successful argument is true.  If this value is false the value(s)\n
+ * for each element is returned.\n
+ *\n
+ * Note: This method *always* returns an array.  If no valid value can be determined the\n
+ *\t   array will be empty, otherwise it will contain one or more values.\n
+ */\n
+$.fn.fieldValue = function(successful) {\n
+\tfor (var val=[], i=0, max=this.length; i < max; i++) {\n
+\t\tvar el = this[i];\n
+\t\tvar v = $.fieldValue(el, successful);\n
+\t\tif (v === null || typeof v == \'undefined\' || (v.constructor == Array && !v.length))\n
+\t\t\tcontinue;\n
+\t\tv.constructor == Array ? $.merge(val, v) : val.push(v);\n
+\t}\n
+\treturn val;\n
+};\n
+\n
+/**\n
+ * Returns the value of the field element.\n
+ */\n
+$.fieldValue = function(el, successful) {\n
+\tvar n = el.name, t = el.type, tag = el.tagName.toLowerCase();\n
+\tif (typeof successful == \'undefined\') successful = true;\n
+\n
+\tif (successful && (!n || el.disabled || t == \'reset\' || t == \'button\' ||\n
+\t\t(t == \'checkbox\' || t == \'radio\') && !el.checked ||\n
+\t\t(t == \'submit\' || t == \'image\') && el.form && el.form.clk != el ||\n
+\t\ttag == \'select\' && el.selectedIndex == -1))\n
+\t\t\treturn null;\n
+\n
+\tif (tag == \'select\') {\n
+\t\tvar index = el.selectedIndex;\n
+\t\tif (index < 0) return null;\n
+\t\tvar a = [], ops = el.options;\n
+\t\tvar one = (t == \'select-one\');\n
+\t\tvar max = (one ? index+1 : ops.length);\n
+\t\tfor(var i=(one ? index : 0); i < max; i++) {\n
+\t\t\tvar op = ops[i];\n
+\t\t\tif (op.selected) {\n
+\t\t\t\tvar v = op.value;\n
+\t\t\t\tif (!v) // extra pain for IE...\n
+\t\t\t\t\tv = (op.attributes && op.attributes[\'value\'] && !(op.attributes[\'value\'].specified)) ? op.text : op.value;\n
+\t\t\t\tif (one) return v;\n
+\t\t\t\ta.push(v);\n
+\t\t\t}\n
+\t\t}\n
+\t\treturn a;\n
+\t}\n
+\treturn el.value;\n
+};\n
+\n
+/**\n
+ * Clears the form data.  Takes the following actions on the form\'s input fields:\n
+ *  - input text fields will have their \'value\' property set to the empty string\n
+ *  - select elements will have their \'selectedIndex\' property set to -1\n
+ *  - checkbox and radio inputs will have their \'checked\' property set to false\n
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected\n
+ *  - button elements will *not* be effected\n
+ */\n
+$.fn.clearForm = function() {\n
+\treturn this.each(function() {\n
+\t\t$(\'input,select,textarea\', this).clearFields();\n
+\t});\n
+};\n
+\n
+/**\n
+ * Clears the selected form elements.\n
+ */\n
+$.fn.clearFields = $.fn.clearInputs = function() {\n
+\treturn this.each(function() {\n
+\t\tvar t = this.type, tag = this.tagName.toLowerCase();\n
+\t\tif (t == \'text\' || t == \'password\' || tag == \'textarea\')\n
+\t\t\tthis.value = \'\';\n
+\t\telse if (t == \'checkbox\' || t == \'radio\')\n
+\t\t\tthis.checked = false;\n
+\t\telse if (tag == \'select\')\n
+\t\t\tthis.selectedIndex = -1;\n
+\t});\n
+};\n
+\n
+/**\n
+ * Resets the form data.  Causes all form elements to be reset to their original value.\n
+ */\n
+$.fn.resetForm = function() {\n
+\treturn this.each(function() {\n
+\t\t// guard against an input with the name of \'reset\'\n
+\t\t// note that IE reports the reset function as an \'object\'\n
+\t\tif (typeof this.reset == \'function\' || (typeof this.reset == \'object\' && !this.reset.nodeType))\n
+\t\t\tthis.reset();\n
+\t});\n
+};\n
+\n
+/**\n
+ * Enables or disables any matching elements.\n
+ */\n
+$.fn.enable = function(b) {\n
+\tif (b == undefined) b = true;\n
+\treturn this.each(function() {\n
+\t\tthis.disabled = !b;\n
+\t});\n
+};\n
+\n
+/**\n
+ * Checks/unchecks any matching checkboxes or radio buttons and\n
+ * selects/deselects and matching option elements.\n
+ */\n
+$.fn.selected = function(select) {\n
+\tif (select == undefined) select = true;\n
+\treturn this.each(function() {\n
+\t\tvar t = this.type;\n
+\t\tif (t == \'checkbox\' || t == \'radio\')\n
+\t\t\tthis.checked = select;\n
+\t\telse if (this.tagName.toLowerCase() == \'option\') {\n
+\t\t\tvar $sel = $(this).parent(\'select\');\n
+\t\t\tif (select && $sel[0] && $sel[0].type == \'select-one\') {\n
+\t\t\t\t// deselect all other options\n
+\t\t\t\t$sel.find(\'option\').selected(false);\n
+\t\t\t}\n
+\t\t\tthis.selected = select;\n
+\t\t}\n
+\t});\n
+};\n
+\n
+// helper fn for console logging\n
+// set $.fn.ajaxSubmit.debug to true to enable debug logging\n
+function log() {\n
+\tif ($.fn.ajaxSubmit.debug) {\n
+\t\tvar msg = \'[jquery.form] \' + Array.prototype.join.call(arguments,\'\');\n
+\t\tif (window.console && window.console.log)\n
+\t\t\twindow.console.log(msg);\n
+\t\telse if (window.opera && window.opera.postError)\n
+\t\t\twindow.opera.postError(msg);\n
+\t}\n
+};\n
+\n
+})(jQuery);\n
+
+
+]]></string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>size</string> </key>
+            <value> <int>20805</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>formplugin.js</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/change_log b/bt5/erp5_jquery_plugin_formplugin/bt/change_log
new file mode 100644
index 0000000000..e1d0b8a2b6
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/change_log
@@ -0,0 +1,2 @@
+2012-12-14 lingnan
+* Initial commit
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/copyright_list b/bt5/erp5_jquery_plugin_formplugin/bt/copyright_list
new file mode 100644
index 0000000000..f9342e8df2
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/copyright_list
@@ -0,0 +1 @@
+2012 (c) Nexedi SA
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/dependency_list b/bt5/erp5_jquery_plugin_formplugin/bt/dependency_list
new file mode 100644
index 0000000000..a3d3a39331
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/dependency_list
@@ -0,0 +1 @@
+erp5_jquery
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/description b/bt5/erp5_jquery_plugin_formplugin/bt/description
new file mode 100644
index 0000000000..dc40e2823a
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/description
@@ -0,0 +1,2 @@
+This  Business Template contains only static files of formplugin library 2.43.
+* http://malsup.com/jquery/form/
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/license b/bt5/erp5_jquery_plugin_formplugin/bt/license
new file mode 100644
index 0000000000..e6816b9c6b
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/license
@@ -0,0 +1 @@
+MIT/GPL
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/maintainer_list b/bt5/erp5_jquery_plugin_formplugin/bt/maintainer_list
new file mode 100644
index 0000000000..23166f16ce
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/maintainer_list
@@ -0,0 +1 @@
+lingnan
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/revision b/bt5/erp5_jquery_plugin_formplugin/bt/revision
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/revision
@@ -0,0 +1 @@
+2
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/template_format_version b/bt5/erp5_jquery_plugin_formplugin/bt/template_format_version
new file mode 100644
index 0000000000..56a6051ca2
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/template_path_list b/bt5/erp5_jquery_plugin_formplugin/bt/template_path_list
new file mode 100644
index 0000000000..39b1947b72
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/template_path_list
@@ -0,0 +1,2 @@
+portal_skins/erp5_jquery/jquery/plugin/formplugin
+portal_skins/erp5_jquery/jquery/plugin/formplugin/**
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/title b/bt5/erp5_jquery_plugin_formplugin/bt/title
new file mode 100644
index 0000000000..6b274a7fed
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/title
@@ -0,0 +1 @@
+erp5_jquery_plugin_formplugin
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formplugin/bt/version b/bt5/erp5_jquery_plugin_formplugin/bt/version
new file mode 100644
index 0000000000..48360de846
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formplugin/bt/version
@@ -0,0 +1 @@
+5.4.7
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard.xml b/bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard.xml
new file mode 100644
index 0000000000..0d55f31b6b
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Folder" module="OFS.Folder"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>formwizard</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard/formwizard.js.xml b/bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard/formwizard.js.xml
new file mode 100644
index 0000000000..39c0c3a969
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/formwizard/formwizard.js.xml
@@ -0,0 +1,508 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_EtagSupport__etag</string> </key>
+            <value> <string>ts54096599.77</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>formwizard.js</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>application/javascript</string> </value>
+        </item>
+        <item>
+            <key> <string>data</string> </key>
+            <value> <string encoding="cdata"><![CDATA[
+
+/*\n
+ * jQuery wizard plug-in 3.0.7 (18-SEPT-2012)\n
+ *\n
+ *\n
+ * Copyright (c) 2012 Jan Sundman (jan.sundman[at]aland.net)\n
+ *\n
+ * http://www.thecodemine.org\n
+ *\n
+ * Licensed under the MIT licens:\n
+ *   http://www.opensource.org/licenses/mit-license.php\n
+ *\n
+ */\n
+\n
+\n
+(function($){\n
+\t$.widget("ui.formwizard", {\n
+\n
+\t\t_init: function() {\n
+\n
+\t\t\tvar wizard = this;\n
+\t\t\tvar formOptionsSuccess = this.options.formOptions.success;\n
+\t\t\tvar formOptionsComplete = this.options.formOptions.complete;\n
+\t\t\tvar formOptionsBeforeSend = this.options.formOptions.beforeSend;\n
+\t\t\tvar formOptionsBeforeSubmit = this.options.formOptions.beforeSubmit;\n
+\t\t\tvar formOptionsBeforeSerialize = this.options.formOptions.beforeSerialize;\n
+\t\t\tthis.options.formOptions = $.extend(this.options.formOptions,{\n
+\t\t\t\tsuccess\t: function(responseText, textStatus, xhr){\n
+\t\t\t\t\tif(formOptionsSuccess){\n
+\t\t\t\t\t\tformOptionsSuccess(responseText, textStatus, xhr);\n
+\t\t\t\t\t}\n
+\t\t\t\t\tif(wizard.options.formOptions && wizard.options.formOptions.resetForm || !wizard.options.formOptions){\n
+\t\t\t\t\t\twizard._reset();\n
+\t\t\t\t\t}\n
+\t\t\t\t},\n
+\t\t\t\tcomplete : function(xhr, textStatus){\n
+\t\t\t\t\tif(formOptionsComplete){\n
+\t\t\t\t\t\tformOptionsComplete(xhr, textStatus);\n
+\t\t\t\t\t}\n
+\t\t\t\t\twizard._enableNavigation();\n
+\t\t\t\t},\n
+\t\t\t\tbeforeSubmit : function(arr, theForm, options) {\n
+\t\t\t\t\tif(formOptionsBeforeSubmit){\n
+\t\t\t\t\t\tvar shouldSubmit = formOptionsBeforeSubmit(arr, theForm, options);\n
+\t\t\t\t\t\tif(!shouldSubmit)\n
+\t\t\t\t\t\t\twizard._enableNavigation();\n
+\t\t\t\t\t\treturn shouldSubmit;\n
+\t\t\t\t\t}\n
+\t\t\t\t},\n
+\t\t\t\tbeforeSend : function(xhr) {\n
+\t\t\t\t\tif(formOptionsBeforeSend){\n
+\t\t\t\t\t\tvar shouldSubmit = formOptionsBeforeSend(xhr);\n
+\t\t\t\t\t\tif(!shouldSubmit)\n
+\t\t\t\t\t\t\twizard._enableNavigation();\n
+\t\t\t\t\t\treturn shouldSubmit;\n
+\t\t\t\t\t}\n
+\t\t\t\t},\n
+\t\t\t\tbeforeSerialize: function(form, options) {\n
+\t\t\t\t\tif(formOptionsBeforeSerialize){\n
+\t\t\t\t\t\tvar shouldSubmit = formOptionsBeforeSerialize(form, options);\n
+\t\t\t\t\t\tif(!shouldSubmit)\n
+\t\t\t\t\t\t\twizard._enableNavigation();\n
+\t\t\t\t\t\treturn shouldSubmit;\n
+\t\t\t\t\t}\n
+\t\t\t\t}\n
+\t\t\t});\n
+\t\t\t\n
+\t\t\tif (this.options.historyEnabled) {\n
+\t\t\t\t$.bbq.removeState("_" + $(this.element).attr(\'id\'));\n
+\t\t\t}\n
+\n
+\t\t\tthis.steps = this.element.find(".step").hide();\n
+\n
+\t\t\tthis.firstStep = this.steps.eq(0).attr("id");\n
+\t\t\tthis.activatedSteps = new Array();\n
+\t\t\tthis.isLastStep = false;\n
+\t\t\tthis.previousStep = undefined;\n
+\t\t\tthis.currentStep = this.steps.eq(0).attr("id");\n
+\t\t\tthis.nextButton\t= this.element.find(this.options.next)\n
+\t\t\t\t\t.click(function() {\n
+\t\t\t\t\t\treturn wizard._next();\n
+\t\t\t\t\t});\n
+\n
+\t\t\tthis.nextButtonInitinalValue = this.nextButton.val();\n
+\t\t\tthis.nextButton.val(this.options.textNext);\n
+\n
+\t\t\t\tthis.backButton\t= this.element.find(this.options.back)\n
+\t\t\t\t\t.click(function() {\n
+\t\t\t\t\t\twizard._back();return false;\n
+\t\t\t\t\t});\n
+\n
+\t\t\t\tthis.backButtonInitinalValue = this.backButton.val();\n
+\t\t\t\tthis.backButton.val(this.options.textBack);\n
+\n
+\t\t\tif(this.options.validationEnabled && jQuery().validate  == undefined){\n
+\t\t\t\tthis.options.validationEnabled = false;\n
+\t\t\t\tif( (window[\'console\'] !== undefined) ){\n
+\t\t\t\t\tconsole.log("%s", "validationEnabled option set, but the validation plugin is not included");\n
+\t\t\t\t}\n
+\t\t\t}else if(this.options.validationEnabled){\n
+\t\t\t\tthis.element.validate(this.options.validationOptions);\n
+\t\t\t}\n
+\t\t\tif(this.options.formPluginEnabled && jQuery().ajaxSubmit == undefined){\n
+\t\t\t\tthis.options.formPluginEnabled = false;\n
+\t\t\t\tif( (window[\'console\'] !== undefined) ){\n
+\t\t\t\t\tconsole.log("%s", "formPluginEnabled option set but the form plugin is not included");\n
+\t\t\t\t}\n
+\t\t\t}\n
+\n
+\t\t\tif(this.options.disableInputFields == true){\n
+\t\t\t\t$(this.steps).find(":input:not(\'.wizard-ignore\')").attr("disabled","disabled");\n
+\t\t\t}\n
+\n
+\t\t\tif(this.options.historyEnabled){\n
+\t\t\t\t$(window).bind(\'hashchange\', undefined, function(event){\n
+\t\t\t\t\tvar hashStep = event.getState( "_" + $(wizard.element).attr( \'id\' )) || wizard.firstStep;\n
+\t\t\t\t\tif(hashStep !== wizard.currentStep){\n
+\t\t\t\t\t\tif(wizard.options.validationEnabled && hashStep === wizard._navigate(wizard.currentStep)){\n
+\t\t\t\t\t\t\tif(!wizard.element.valid()){\n
+\t\t\t\t\t\t\t\twizard._updateHistory(wizard.currentStep);\n
+\t\t\t\t\t\t\t\twizard.element.validate().focusInvalid();\n
+\n
+\t\t\t\t\t\t\t\treturn false;\n
+\t\t\t\t\t\t\t}\n
+\t\t\t\t\t\t}\n
+\t\t\t\t\t\tif(hashStep !== wizard.currentStep)\n
+\t\t\t\t\t\t\twizard._show(hashStep);\n
+\t\t\t\t\t}\n
+\t\t\t\t});\n
+\t\t\t}\n
+\n
+\t\t\tthis.element.addClass("ui-formwizard");\n
+\t\t\tthis.element.find(":input").addClass("ui-wizard-content");\n
+\t\t\tthis.steps.addClass("ui-formwizard-content");\n
+\t\t\tthis.backButton.addClass("ui-formwizard-button ui-wizard-content");\n
+\t\t\tthis.nextButton.addClass("ui-formwizard-button ui-wizard-content");\n
+\n
+\t\t\tif(!this.options.disableUIStyles){\n
+\t\t\t\tthis.element.addClass("ui-helper-reset ui-widget ui-widget-content ui-helper-reset ui-corner-all");\n
+\t\t\t\tthis.element.find(":input").addClass("ui-helper-reset ui-state-default");\n
+\t\t\t\tthis.steps.addClass("ui-helper-reset ui-corner-all");\n
+\t\t\t\tthis.backButton.addClass("ui-helper-reset ui-state-default");\n
+\t\t\t\tthis.nextButton.addClass("ui-helper-reset ui-state-default");\n
+\t\t\t}\n
+\t\t\tthis._show(undefined);\n
+\t\t\treturn $(this);\n
+\t\t},\n
+\n
+\t\t_next : function(){\n
+\t\t\tif(this.options.validationEnabled){\n
+\t\t\t\tif(!this.element.valid()){\n
+\t\t\t\t\tthis.element.validate().focusInvalid();\n
+\t\t\t\t\treturn false;\n
+\t\t\t\t}\n
+\t\t\t}\n
+\n
+\t\t\tif(this.options.remoteAjax != undefined){\n
+\t\t\t\tvar options = this.options.remoteAjax[this.currentStep];\n
+\t\t\t\tvar wizard = this;\n
+\t\t\t\tif(options !== undefined){\n
+\t\t\t\t\tvar success = options.success;\n
+\t\t\t\t\tvar beforeSend = options.beforeSend;\n
+\t\t\t\t\tvar complete = options.complete;\n
+\n
+\t\t\t\t\toptions = $.extend({},options,{\n
+\t\t\t\t\t\tsuccess: function(data, statusText){\n
+\t\t\t\t\t\t\tif((success !== undefined && success(data, statusText)) || (success == undefined)){\n
+\t\t\t\t\t\t\t\twizard._continueToNextStep();\n
+\t\t\t\t\t\t\t}\n
+\t\t\t\t\t\t},\n
+\t\t\t\t\t\tbeforeSend : function(xhr){\n
+\t\t\t\t\t\t\twizard._disableNavigation();\n
+\t\t\t\t\t\t\tif(beforeSend !== undefined)\n
+\t\t\t\t\t\t\t\tbeforeSend(xhr);\n
+\t\t\t\t\t\t\t$(wizard.element).trigger(\'before_remote_ajax\', {"currentStep" : wizard.currentStep});\n
+\t\t\t\t\t\t},\n
+\t\t\t\t\t\tcomplete : function(xhr, statusText){\n
+\t\t\t\t\t\t\tif(complete !== undefined)\n
+\t\t\t\t\t\t\t\tcomplete(xhr, statusText);\n
+\t\t\t\t\t\t\t$(wizard.element).trigger(\'after_remote_ajax\', {"currentStep" : wizard.currentStep});\n
+\t\t\t\t\t\t\twizard._enableNavigation();\n
+\t\t\t\t\t\t}\n
+\t\t\t\t\t})\n
+\t\t\t\t\tthis.element.ajaxSubmit(options);\n
+\t\t\t\t\treturn false;\n
+\t\t\t\t}\n
+\t\t\t}\n
+\n
+\t\t\treturn this._continueToNextStep();\n
+\t\t},\n
+\n
+\t\t_back : function(){\n
+\t\t\tif(this.activatedSteps.length > 0){\n
+\t\t\t\tif(this.options.historyEnabled){\n
+\t\t\t\t\tthis._updateHistory(this.activatedSteps[this.activatedSteps.length - 2]);\n
+\t\t\t\t}else{\n
+\t\t\t\t\tthis._show(this.activatedSteps[this.activatedSteps.length - 2], true);\n
+\t\t\t\t}\n
+\t\t\t}\n
+\t\t\treturn false;\n
+\t\t},\n
+\n
+\t\t_continueToNextStep : function(){\n
+\t\t\tif(this.isLastStep){\n
+\t\t\t\tfor(var i = 0; i < this.activatedSteps.length; i++){\n
+\t\t\t\t\tthis.steps.filter("#" + this.activatedSteps[i]).find(":input").not(".wizard-ignore").removeAttr("disabled");\n
+\t\t\t\t}\n
+\t\t\t\tif(!this.options.formPluginEnabled){\n
+\t\t\t\t\treturn true;\n
+\t\t\t\t}else{\n
+\t\t\t\t\tthis._disableNavigation();\n
+\t\t\t\t\tthis.element.ajaxSubmit(this.options.formOptions);\n
+\t\t\t\t\treturn false;\n
+\t\t\t\t}\n
+\t\t\t}\n
+\n
+\t\t\tvar step = this._navigate(this.currentStep);\n
+\t\t\tif(step == this.currentStep){\n
+\t\t\t\treturn false;\n
+\t\t\t}\n
+\t\t\tif(this.options.historyEnabled){\n
+\t\t\t\tthis._updateHistory(step);\n
+\t\t\t}else{\n
+\t\t\t\tthis._show(step, true);\n
+\t\t\t}\n
+\t\t\treturn false;\n
+\t\t},\n
+\n
+\t\t_updateHistory : function(step){\n
+\t\t\tvar state = {};\n
+\t\t\tstate["_" + $(this.element).attr(\'id\')] = step;\n
+\t\t\t$.bbq.pushState(state);\n
+\t\t},\n
+\n
+\t\t_disableNavigation : function(){\n
+\t\t\tthis.nextButton.attr("disabled","disabled");\n
+\t\t\tthis.backButton.attr("disabled","disabled");\n
+\t\t\tif(!this.options.disableUIStyles){\n
+\t\t\t\tthis.nextButton.removeClass("ui-state-active").addClass("ui-state-disabled");\n
+\t\t\t\tthis.backButton.removeClass("ui-state-active").addClass("ui-state-disabled");\n
+\t\t\t}\n
+\t\t},\n
+\n
+\t\t_enableNavigation : function(){\n
+\t\t\tif(this.isLastStep){\n
+\t\t\t\tthis.nextButton.val(this.options.textSubmit);\n
+\t\t\t}else{\n
+\t\t\t\tthis.nextButton.val(this.options.textNext);\n
+\t\t\t}\n
+\n
+\t\t\tif($.trim(this.currentStep) !== this.steps.eq(0).attr("id")){\n
+\t\t\t\tthis.backButton.removeAttr("disabled");\n
+\t\t\t\tif(!this.options.disableUIStyles){\n
+\t\t\t\t\tthis.backButton.removeClass("ui-state-disabled").addClass("ui-state-active");\n
+\t\t\t\t}\n
+\t\t\t}\n
+\n
+\t\t\tthis.nextButton.removeAttr("disabled");\n
+\t\t\tif(!this.options.disableUIStyles){\n
+\t\t\t\tthis.nextButton.removeClass("ui-state-disabled").addClass("ui-state-active");\n
+\t\t\t}\n
+\t\t},\n
+\n
+\t\t_animate : function(oldStep, newStep, stepShownCallback){\n
+\t\t\tthis._disableNavigation();\n
+\t\t\tvar old = this.steps.filter("#" + oldStep);\n
+\t\t\tvar current = this.steps.filter("#" + newStep);\n
+\t\t\told.find(":input").not(".wizard-ignore").attr("disabled","disabled");\n
+\t\t\tcurrent.find(":input").not(".wizard-ignore").removeAttr("disabled");\n
+\t\t\tvar wizard = this;\n
+\t\t\told.animate(wizard.options.outAnimation, wizard.options.outDuration, wizard.options.easing, function(){\n
+\t\t\t\tcurrent.animate(wizard.options.inAnimation, wizard.options.inDuration, wizard.options.easing, function(){\n
+\t\t\t\t\tif(wizard.options.focusFirstInput)\n
+\t\t\t\t\t\tcurrent.find(":input:first").focus();\n
+\t\t\t\t\twizard._enableNavigation();\n
+\n
+\t\t\t\t\tstepShownCallback.apply(wizard);\n
+\t\t\t\t});\n
+\t\t\t\treturn;\n
+\t\t\t});\n
+\t\t},\n
+\n
+\t\t_checkIflastStep : function(step){\n
+\t\t\tthis.isLastStep = false;\n
+\t\t\tif($("#" + step).hasClass(this.options.submitStepClass) || this.steps.filter(":last").attr("id") == step){\n
+\t\t\t\tthis.isLastStep = true;\n
+\t\t\t}\n
+\t\t},\n
+\n
+\t\t_getLink : function(step){\n
+\t\t\tvar link = undefined;\n
+\t\t\tvar links = this.steps.filter("#" + step).find(this.options.linkClass);\n
+\n
+\t\t\tif(links != undefined){\n
+\t\t\t\tif(links.filter(":radio,:checkbox").size() > 0){\n
+\t\t\t\t\tlink = links.filter(this.options.linkClass + ":checked").val();\n
+\t\t\t\t}else{\n
+\t\t\t\t\tlink = $(links).val();\n
+\t\t\t\t}\n
+\t\t\t}\n
+\t\t\treturn link;\n
+\t\t},\n
+\n
+\t\t_navigate : function(step){\n
+\t\t\tvar link = this._getLink(step);\n
+\t\t\tif(link != undefined){\n
+\t\t\t\tif((link != "" && link != null && link != undefined) && this.steps.filter("#" + link).attr("id") != undefined){\n
+\t\t\t\t\treturn link;\n
+\t\t\t\t}\n
+\t\t\t\treturn this.currentStep;\n
+\t\t\t}else if(link == undefined && !this.isLastStep){\n
+\t\t\t\tvar step1 =  this.steps.filter("#" + step).next().attr("id");\n
+\t\t\t\treturn step1;\n
+\t\t\t}\n
+\t\t},\n
+\n
+\t\t_show : function(step){\n
+\t\t\tvar backwards = false;\n
+\t\t\tvar triggerStepShown = step !== undefined;\n
+\t\t\tif(step == undefined || step == ""){\n
+\t\t\t\t\tthis.activatedSteps.pop();\n
+\t\t\t\t\tstep = this.firstStep;\n
+\t\t\t\t\tthis.activatedSteps.push(step);\n
+\t\t\t}else{\n
+\t\t\t\tif($.inArray(step, this.activatedSteps) > -1){\n
+\t\t\t\t\tbackwards = true;\n
+\t\t\t\t\tthis.activatedSteps.pop();\n
+\t\t\t\t}else {\n
+\t\t\t\t\tthis.activatedSteps.push(step);\n
+\t\t\t\t}\n
+\t\t\t}\n
+\n
+\t\t\tif(this.currentStep !== step || step === this.firstStep){\n
+\t\t\t\tthis.previousStep = this.currentStep;\n
+\t\t\t\tthis._checkIflastStep(step);\n
+\t\t\t\tthis.currentStep = step;\n
+\t\t\t\tvar stepShownCallback = function(){if(triggerStepShown){$(this.element).trigger(\'step_shown\', $.extend({"isBackNavigation" : backwards},this._state()));}}\n
+\t\t\t\tif(triggerStepShown){\n
+\t\t\t\t\t$(this.element).trigger(\'before_step_shown\', $.extend({"isBackNavigation" : backwards},this._state()));\n
+\t\t\t\t}\n
+\t\t\t\tthis._animate(this.previousStep, step, stepShownCallback);\n
+\t\t\t};\n
+\n
+\n
+\t\t},\n
+\n
+\t   _reset : function(){\n
+\t\t\tthis.element.resetForm()\n
+\t\t\t$("label,:input,textarea",this).removeClass("error");\n
+\t\t\tfor(var i = 0; i < this.activatedSteps.length; i++){\n
+\t\t\t\tthis.steps.filter("#" + this.activatedSteps[i]).hide().find(":input").attr("disabled","disabled");\n
+\t\t\t}\n
+\t\t\tthis.activatedSteps = new Array();\n
+\t\t\tthis.previousStep = undefined;\n
+\t\t\tthis.isLastStep = false;\n
+\t\t\tif(this.options.historyEnabled){\n
+\t\t\t\tthis._updateHistory(this.firstStep);\n
+\t\t\t}else{\n
+\t\t\t\tthis._show(this.firstStep);\n
+\t\t\t}\n
+\n
+\t\t},\n
+\n
+\t\t_state : function(state){\n
+\t\t\tvar currentState = { "settings" : this.options,\n
+\t\t\t\t"activatedSteps" : this.activatedSteps,\n
+\t\t\t\t"isLastStep" : this.isLastStep,\n
+\t\t\t\t"isFirstStep" : this.currentStep === this.firstStep,\n
+\t\t\t\t"previousStep" : this.previousStep,\n
+\t\t\t\t"currentStep" : this.currentStep,\n
+\t\t\t\t"backButton" : this.backButton,\n
+\t\t\t\t"nextButton" : this.nextButton,\n
+\t\t\t\t"steps" : this.steps,\n
+\t\t\t\t"firstStep" : this.firstStep\n
+\t\t\t}\n
+\n
+\t\t\tif(state !== undefined)\n
+\t\t\t\treturn currentState[state];\n
+\n
+\t\t\treturn currentState;\n
+\t\t},\n
+\n
+\t  /*Methods*/\n
+\n
+\t\tshow : function(step){\n
+\t\t\tif(this.options.historyEnabled){\n
+\t\t\t\tthis._updateHistory(step);\n
+\t\t\t}else{\n
+\t\t\t\tthis._show(step);\n
+\t\t\t}\n
+\t\t},\n
+\n
+\t\tstate : function(state){\n
+\t\t\treturn this._state(state);\n
+\t\t},\n
+\n
+\t\treset : function(){\n
+\t\t\tthis._reset();\n
+\t\t},\n
+\n
+\t\tnext : function(){\n
+\t\t\tthis._next();\n
+\t\t},\n
+\n
+\t\tback : function(){\n
+\t\t\tthis._back();\n
+\t\t},\n
+\n
+\t\tdestroy: function() {\n
+\t\t\tthis.element.find("*").removeAttr("disabled").show();\n
+\t\t\tthis.nextButton.unbind("click").val(this.nextButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");\n
+\t\t\tthis.backButton.unbind("click").val(this.backButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");\n
+\t\t\tthis.backButtonInitinalValue = undefined;\n
+\t\t\tthis.nextButtonInitinalValue = undefined;\n
+\t\t\tthis.activatedSteps = undefined;\n
+\t\t\tthis.previousStep = undefined;\n
+\t\t\tthis.currentStep = undefined;\n
+\t\t\tthis.isLastStep = undefined;\n
+\t\t\tthis.options = undefined;\n
+\t\t\tthis.nextButton = undefined;\n
+\t\t\tthis.backButton = undefined;\n
+\t\t\tthis.formwizard = undefined;\n
+\t\t\tthis.element = undefined;\n
+\t\t\tthis.steps = undefined;\n
+\t\t\tthis.firstStep = undefined;\n
+\t\t},\n
+\n
+\t\tupdate_steps : function(){\n
+\t\t\tthis.steps = this.element.find(".step").addClass("ui-formwizard-content");\n
+\t\t\tthis.firstStep = this.steps.eq(0).attr("id");\n
+\t\t\tthis.steps.not("#" + this.currentStep).hide().find(":input").addClass("ui-wizard-content").attr("disabled","disabled");\n
+\t\t\tthis._checkIflastStep(this.currentStep);\n
+\t\t\tthis._enableNavigation();\n
+\t\t\tif(!this.options.disableUIStyles){\n
+\t\t\t\tthis.steps.addClass("ui-helper-reset ui-corner-all");\n
+\t\t\t\tthis.steps.find(":input").addClass("ui-helper-reset ui-state-default");\n
+\t\t\t}\n
+\t\t},\n
+\n
+\t\toptions: {\n
+\t   \t\thistoryEnabled\t: false,\n
+\t\t\tvalidationEnabled : false,\n
+\t\t\tvalidationOptions : undefined,\n
+\t\t\tformPluginEnabled : false,\n
+\t\t\tlinkClass\t: ".link",\n
+\t\t\tsubmitStepClass : "submit_step",\n
+\t\t\tback : ":reset",\n
+\t\t\tnext : ":submit",\n
+\t\t\ttextSubmit : \'Submit\',\n
+\t\t\ttextNext : \'Next\',\n
+\t\t\ttextBack : \'Back\',\n
+\t\t\tremoteAjax : undefined,\n
+\t\t\tinAnimation : {opacity: \'show\'},\n
+\t\t\toutAnimation: {opacity: \'hide\'},\n
+\t\t\tinDuration : 400,\n
+\t\t\toutDuration: 400,\n
+\t\t\teasing: \'swing\',\n
+\t\t\tfocusFirstInput : false,\n
+\t\t\tdisableInputFields : true,\n
+\t\t\tformOptions : { reset: true, success: function(data) { if( (window[\'console\'] !== undefined) ){console.log("%s", "form submit successful");}},\n
+\t\t\tdisableUIStyles : false\n
+\t\t}\n
+   }\n
+ });\n
+})(jQuery);\n
+
+
+]]></string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>size</string> </key>
+            <value> <int>14327</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>formwizard.js</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/change_log b/bt5/erp5_jquery_plugin_formwizard/bt/change_log
new file mode 100644
index 0000000000..e1d0b8a2b6
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/change_log
@@ -0,0 +1,2 @@
+2012-12-14 lingnan
+* Initial commit
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/copyright_list b/bt5/erp5_jquery_plugin_formwizard/bt/copyright_list
new file mode 100644
index 0000000000..f9342e8df2
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/copyright_list
@@ -0,0 +1 @@
+2012 (c) Nexedi SA
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/dependency_list b/bt5/erp5_jquery_plugin_formwizard/bt/dependency_list
new file mode 100644
index 0000000000..a3d3a39331
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/dependency_list
@@ -0,0 +1 @@
+erp5_jquery
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/description b/bt5/erp5_jquery_plugin_formwizard/bt/description
new file mode 100644
index 0000000000..3e43b82d78
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/description
@@ -0,0 +1,2 @@
+This  Business Template contains only static files of formwizard library 3.0.7.
+* http://thecodemine.org/
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/license b/bt5/erp5_jquery_plugin_formwizard/bt/license
new file mode 100644
index 0000000000..8ab70c0254
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/license
@@ -0,0 +1 @@
+MIT
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/maintainer_list b/bt5/erp5_jquery_plugin_formwizard/bt/maintainer_list
new file mode 100644
index 0000000000..23166f16ce
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/maintainer_list
@@ -0,0 +1 @@
+lingnan
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/revision b/bt5/erp5_jquery_plugin_formwizard/bt/revision
new file mode 100644
index 0000000000..e440e5c842
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/revision
@@ -0,0 +1 @@
+3
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/template_format_version b/bt5/erp5_jquery_plugin_formwizard/bt/template_format_version
new file mode 100644
index 0000000000..56a6051ca2
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/template_path_list b/bt5/erp5_jquery_plugin_formwizard/bt/template_path_list
new file mode 100644
index 0000000000..12a3d295da
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/template_path_list
@@ -0,0 +1,2 @@
+portal_skins/erp5_jquery/jquery/plugin/formwizard
+portal_skins/erp5_jquery/jquery/plugin/formwizard/**
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/title b/bt5/erp5_jquery_plugin_formwizard/bt/title
new file mode 100644
index 0000000000..f66661aad6
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/title
@@ -0,0 +1 @@
+erp5_jquery_plugin_formwizard
\ No newline at end of file
diff --git a/bt5/erp5_jquery_plugin_formwizard/bt/version b/bt5/erp5_jquery_plugin_formwizard/bt/version
new file mode 100644
index 0000000000..48360de846
--- /dev/null
+++ b/bt5/erp5_jquery_plugin_formwizard/bt/version
@@ -0,0 +1 @@
+5.4.7
\ No newline at end of file
-- 
2.30.9