[Jifty-commit] r3209 - in jifty/branches/virtual-models: . debian doc doc/talks examples/Doxory examples/Doxory/bin examples/Doxory/doc examples/Doxory/etc examples/Doxory/lib examples/Doxory/lib/Doxory examples/Doxory/lib/Doxory/Action examples/Doxory/lib/Doxory/Model examples/Doxory/log examples/Doxory/share examples/Doxory/share/po examples/Doxory/share/web examples/Doxory/share/web/static examples/Doxory/share/web/templates examples/Doxory/t examples/Doxory/var examples/Doxory/var/mason examples/Example-Todo examples/Example-Todo/bin examples/Example-Todo/doc examples/Example-Todo/etc examples/Example-Todo/inc examples/Example-Todo/inc/.author examples/Example-Todo/inc/Module examples/Example-Todo/inc/Module/Install examples/Example-Todo/lib examples/Example-Todo/lib/Example examples/Example-Todo/lib/Example/Todo examples/Example-Todo/lib/Example/Todo/Action examples/Example-Todo/lib/Example/Todo/Model examples/Example-Todo/log examples/Example-Todo/share examples/Example-Todo/share/po examples/Example-Todo/share/web examples/Example-Todo/share/web/static examples/Example-Todo/share/web/templates examples/Example-Todo/t inc/Module inc/Module/Install lib lib/Jifty lib/Jifty/Action lib/Jifty/Manual lib/Jifty/Module lib/Jifty/Plugin lib/Jifty/Plugin/AdminUI lib/Jifty/Plugin/Authentication lib/Jifty/Plugin/Authentication/Password lib/Jifty/Plugin/Authentication/Password/Action lib/Jifty/Plugin/Authentication/Password/Mixin/Model lib/Jifty/Plugin/ErrorTemplates lib/Jifty/Plugin/OnlineDocs lib/Jifty/Plugin/REST lib/Jifty/Plugin/SkeletonApp lib/Jifty/Plugin/User/Mixin/Model lib/Jifty/Script lib/Jifty/Server lib/Jifty/Server/Prefork lib/Jifty/Subs lib/Jifty/Test/WWW lib/Jifty/View/Declare lib/Jifty/View/Mason lib/Jifty/View/Static lib/Jifty/Web lib/Jifty/Web/Form lib/Jifty/Web/Form/Field lib/Jifty/Web/Session lib/auto plugins/DumpDispatcher plugins/DumpDispatcher/doc plugins/DumpDispatcher/lib plugins/DumpDispatcher/lib/Jifty plugins/DumpDispatcher/lib/Jifty/Plugin plugins/DumpDispatcher/share plugins/DumpDispatcher/share/po plugins/DumpDispatcher/share/web plugins/DumpDispatcher/share/web/static plugins/DumpDispatcher/share/web/templates plugins/DumpDispatcher/t plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action plugins/ExtJS plugins/ExtJS/doc plugins/ExtJS/lib plugins/ExtJS/lib/Jifty plugins/ExtJS/lib/Jifty/Plugin plugins/ExtJS/lib/Jifty/Plugin/ExtJS plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Action plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Model plugins/ExtJS/share plugins/ExtJS/share/po plugins/ExtJS/share/web plugins/ExtJS/share/web/static plugins/ExtJS/share/web/static/css plugins/ExtJS/share/web/static/css/extjs plugins/ExtJS/share/web/static/images plugins/ExtJS/share/web/static/images/extjs plugins/ExtJS/share/web/static/images/extjs/aero plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog plugins/ExtJS/share/web/static/images/extjs/aero/grid plugins/ExtJS/share/web/static/images/extjs/aero/layout plugins/ExtJS/share/web/static/images/extjs/aero/qtip plugins/ExtJS/share/web/static/images/extjs/aero/sizer plugins/ExtJS/share/web/static/images/extjs/aero/tabs plugins/ExtJS/share/web/static/images/extjs/aero/toolbar plugins/ExtJS/share/web/static/images/extjs/default plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog plugins/ExtJS/share/web/static/images/extjs/default/box plugins/ExtJS/share/web/static/images/extjs/default/dd plugins/ExtJS/share/web/static/images/extjs/default/form plugins/ExtJS/share/web/static/images/extjs/default/grid plugins/ExtJS/share/web/static/images/extjs/default/layout plugins/ExtJS/share/web/static/images/extjs/default/menu plugins/ExtJS/share/web/static/images/extjs/default/qtip plugins/ExtJS/share/web/static/images/extjs/default/shared plugins/ExtJS/share/web/static/images/extjs/default/sizer plugins/ExtJS/share/web/static/images/extjs/default/tabs plugins/ExtJS/share/web/static/images/extjs/default/toolbar plugins/ExtJS/share/web/static/images/extjs/default/tree plugins/ExtJS/share/web/static/images/extjs/gray plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog plugins/ExtJS/share/web/static/images/extjs/gray/grid plugins/ExtJS/share/web/static/images/extjs/gray/layout plugins/ExtJS/share/web/static/images/extjs/gray/menu plugins/ExtJS/share/web/static/images/extjs/gray/qtip plugins/ExtJS/share/web/static/images/extjs/gray/sizer plugins/ExtJS/share/web/static/images/extjs/gray/tabs plugins/ExtJS/share/web/static/images/extjs/gray/toolbar plugins/ExtJS/share/web/static/images/extjs/vista plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog plugins/ExtJS/share/web/static/images/extjs/vista/grid plugins/ExtJS/share/web/static/images/extjs/vista/layout plugins/ExtJS/share/web/static/images/extjs/vista/qtip plugins/ExtJS/share/web/static/images/extjs/vista/sizer plugins/ExtJS/share/web/static/images/extjs/vista/tabs plugins/ExtJS/share/web/static/images/extjs/vista/toolbar plugins/ExtJS/share/web/static/js plugins/ExtJS/share/web/static/js/extjs plugins/ExtJS/share/web/static/js/extjs/adapter plugins/ExtJS/share/web/static/js/extjs/adapter/jquery plugins/ExtJS/share/web/static/js/extjs/adapter/prototype plugins/ExtJS/share/web/static/js/extjs/adapter/yui plugins/ExtJS/share/web/templates plugins/ExtJS/t plugins/WikiToolbar plugins/WikiToolbar/doc plugins/WikiToolbar/lib plugins/WikiToolbar/lib/Jifty plugins/WikiToolbar/lib/Jifty/Plugin plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Action plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Model plugins/WikiToolbar/share plugins/WikiToolbar/share/po plugins/WikiToolbar/share/web/static plugins/WikiToolbar/share/web/static/img plugins/WikiToolbar/share/web/static/img/wt plugins/WikiToolbar/share/web/static/js plugins/WikiToolbar/share/web/templates plugins/WikiToolbar/t plugins/WyzzEditor plugins/WyzzEditor/doc plugins/WyzzEditor/lib plugins/WyzzEditor/lib/Jifty plugins/WyzzEditor/lib/Jifty/Plugin plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor plugins/WyzzEditor/share plugins/WyzzEditor/share/po plugins/WyzzEditor/share/web plugins/WyzzEditor/share/web/static plugins/WyzzEditor/share/web/static/img plugins/WyzzEditor/share/web/static/img/wyzzicons plugins/WyzzEditor/share/web/static/js plugins/WyzzEditor/share/web/static/js/wyzz plugins/WyzzEditor/share/web/static/wyzzstyles plugins/WyzzEditor/share/web/templates plugins/WyzzEditor/t share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs share/po share/web/static/css share/web/static/css/yui/calendar share/web/static/css/yui/menu share/web/static/css/yui/tabview share/web/static/js/yui share/web/templates/_elements t t/Mapper/t t/TestApp-Plugin-PasswordAuth/etc t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model t/TestApp-Plugin-PasswordAuth/t t/TestApp/lib/TestApp t/TestApp/lib/TestApp/View t/TestApp/t

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Mon May 7 16:28:40 EDT 2007


Author: jesse
Date: Mon May  7 16:28:32 2007
New Revision: 3209

Added:
   jifty/branches/virtual-models/doc/notes-on-distributed-operations
   jifty/branches/virtual-models/doc/talks/DoxoryDemo.tgz   (contents, props changed)
   jifty/branches/virtual-models/doc/talks/oscon.2007.dsls.txt
   jifty/branches/virtual-models/doc/talks/present-slides
   jifty/branches/virtual-models/doc/talks/yapc.asia.2007.ja.txt
   jifty/branches/virtual-models/doc/talks/yapc.asia.2007.txt
   jifty/branches/virtual-models/doc/talks/yapcasia2007-doxory.key.tbz2   (contents, props changed)
   jifty/branches/virtual-models/doc/talks/yapcasia2007-doxory.pdf
   jifty/branches/virtual-models/examples/Doxory/
   jifty/branches/virtual-models/examples/Doxory/Makefile.PL
   jifty/branches/virtual-models/examples/Doxory/bin/
   jifty/branches/virtual-models/examples/Doxory/bin/jifty   (contents, props changed)
   jifty/branches/virtual-models/examples/Doxory/doc/
   jifty/branches/virtual-models/examples/Doxory/doxory   (contents, props changed)
   jifty/branches/virtual-models/examples/Doxory/etc/
   jifty/branches/virtual-models/examples/Doxory/etc/config.yml
   jifty/branches/virtual-models/examples/Doxory/lib/
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Action/
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Dispatcher.pm
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/Choice.pm
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/User.pm
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/Vote.pm
   jifty/branches/virtual-models/examples/Doxory/lib/Doxory/View.pm
   jifty/branches/virtual-models/examples/Doxory/log/
   jifty/branches/virtual-models/examples/Doxory/share/
   jifty/branches/virtual-models/examples/Doxory/share/po/
   jifty/branches/virtual-models/examples/Doxory/share/po/zh_cn.po
   jifty/branches/virtual-models/examples/Doxory/share/po/zh_tw.po
   jifty/branches/virtual-models/examples/Doxory/share/web/
   jifty/branches/virtual-models/examples/Doxory/share/web/static/
   jifty/branches/virtual-models/examples/Doxory/share/web/templates/
   jifty/branches/virtual-models/examples/Doxory/t/
   jifty/branches/virtual-models/examples/Doxory/t/00-model-User.t
   jifty/branches/virtual-models/examples/Doxory/var/
   jifty/branches/virtual-models/examples/Doxory/var/mason/
   jifty/branches/virtual-models/examples/Example-Todo/
   jifty/branches/virtual-models/examples/Example-Todo/META.yml
   jifty/branches/virtual-models/examples/Example-Todo/Makefile.PL
   jifty/branches/virtual-models/examples/Example-Todo/bin/
   jifty/branches/virtual-models/examples/Example-Todo/bin/jifty   (contents, props changed)
   jifty/branches/virtual-models/examples/Example-Todo/doc/
   jifty/branches/virtual-models/examples/Example-Todo/etc/
   jifty/branches/virtual-models/examples/Example-Todo/etc/config.yml
   jifty/branches/virtual-models/examples/Example-Todo/inc/
   jifty/branches/virtual-models/examples/Example-Todo/inc/.author/
   jifty/branches/virtual-models/examples/Example-Todo/inc/Module/
   jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/
   jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install.pm
   jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/Base.pm
   jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/Metadata.pm
   jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/WriteAll.pm
   jifty/branches/virtual-models/examples/Example-Todo/lib/
   jifty/branches/virtual-models/examples/Example-Todo/lib/Example/
   jifty/branches/virtual-models/examples/Example-Todo/lib/Example/Todo/
   jifty/branches/virtual-models/examples/Example-Todo/lib/Example/Todo/Action/
   jifty/branches/virtual-models/examples/Example-Todo/lib/Example/Todo/Model/
   jifty/branches/virtual-models/examples/Example-Todo/lib/Example/Todo/Model/Todo.pm
   jifty/branches/virtual-models/examples/Example-Todo/log/
   jifty/branches/virtual-models/examples/Example-Todo/share/
   jifty/branches/virtual-models/examples/Example-Todo/share/po/
   jifty/branches/virtual-models/examples/Example-Todo/share/web/
   jifty/branches/virtual-models/examples/Example-Todo/share/web/static/
   jifty/branches/virtual-models/examples/Example-Todo/share/web/templates/
   jifty/branches/virtual-models/examples/Example-Todo/t/
   jifty/branches/virtual-models/examples/Example-Todo/t/00-model-Todo.t
   jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Server/Prefork/
   jifty/branches/virtual-models/lib/Jifty/Server/Prefork.pm
   jifty/branches/virtual-models/lib/Jifty/Server/Prefork/NetServer.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Form/Field/Collection.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Session/None.pm
   jifty/branches/virtual-models/plugins/DumpDispatcher/
   jifty/branches/virtual-models/plugins/DumpDispatcher/Makefile.PL
   jifty/branches/virtual-models/plugins/DumpDispatcher/doc/
   jifty/branches/virtual-models/plugins/DumpDispatcher/lib/
   jifty/branches/virtual-models/plugins/DumpDispatcher/lib/Jifty/
   jifty/branches/virtual-models/plugins/DumpDispatcher/lib/Jifty/Plugin/
   jifty/branches/virtual-models/plugins/DumpDispatcher/lib/Jifty/Plugin/DumpDispatcher.pm
   jifty/branches/virtual-models/plugins/DumpDispatcher/share/
   jifty/branches/virtual-models/plugins/DumpDispatcher/share/po/
   jifty/branches/virtual-models/plugins/DumpDispatcher/share/web/
   jifty/branches/virtual-models/plugins/DumpDispatcher/share/web/static/
   jifty/branches/virtual-models/plugins/DumpDispatcher/share/web/templates/
   jifty/branches/virtual-models/plugins/DumpDispatcher/t/
   jifty/branches/virtual-models/plugins/ExtJS/
   jifty/branches/virtual-models/plugins/ExtJS/Makefile.PL
   jifty/branches/virtual-models/plugins/ExtJS/doc/
   jifty/branches/virtual-models/plugins/ExtJS/lib/
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS/
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS.pm
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Action/
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Dispatcher.pm
   jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Model/
   jifty/branches/virtual-models/plugins/ExtJS/share/
   jifty/branches/virtual-models/plugins/ExtJS/share/po/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/README.txt
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/basic-dialog.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/box.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/button.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/combo.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/core.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/date-picker.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/dd.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/debug.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ext-all.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/form.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/grid.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/layout.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/menu.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/qtips.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/reset-min.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/resizable.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/tabs.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/toolbar.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/tree.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-aero.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-gray.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-vista.css
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close-over.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-center.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-left.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-right.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse-over.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand-over.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/hd-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/w-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-blue-split.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-hrow.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-split.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-vista-hd.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/pspbrwse.jbf   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort-col-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_asc.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_desc.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-light-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close-on.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/qtip/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/qtip/bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/s.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-btm-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/tb-btn-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-arrow.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/hd-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress2.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/corners-blue.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/corners.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/l-blue.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/l.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/r-blue.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/r.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/tb-blue.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/tb.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-add.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-no.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-yes.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/date-trigger.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/error-tip-corners.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/exclamation.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/text-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/trigger.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/Thumbs.db   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-left-white.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-right-white.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-bottom.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-top.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/dirty.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/done.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-no.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-yes.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/footer-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-hd.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-split.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-hrow.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-loading.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-split.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-vista-hd.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-asc.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-desc.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/invalid_line.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/loading.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/mso-hd.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/nowait.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first-disabled.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last-disabled.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next-disabled.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev-disabled.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/pick-button.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/refresh.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_asc.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_desc.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/wait.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-light-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/stick.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/stuck.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close-on.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/checked.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/group-checked.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/menu-parent.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/menu.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/unchecked.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/tip-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/s.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shadow-lr.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shadow.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/calendar.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/left-btn.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/right-btn.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/warning.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/square.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow-light.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-over-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/gray-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-btn-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-add.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-between.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-no.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-over.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-under.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-yes.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus-nl.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus-nl.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-line.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus-nl.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus-nl.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/folder-open.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/folder.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/leaf.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/loading.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/s.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/dlg-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/hd-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/grid/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/grid/grid-hrow.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-light-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/stick.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close-on.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/checked.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/group-checked.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu-parent.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/unchecked.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/qtip/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/qtip/bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/qtip/tip-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/s.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/gray-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/tb-btn-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-center.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-left.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-right.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/dlg-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/hd-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/w-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/grid/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-split.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-vista-hd.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/gradient-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-collapse.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-expand.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-light-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/stick.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close-on.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/qtip/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/qtip/bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/qtip/tip-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/s.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle-dark.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-left-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-right-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/gray-bg.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/tb-btn-sprite.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/jquery/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/jquery/ext-jquery-adapter.js
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/prototype/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/prototype/ext-prototype-adapter.js
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/ext-yui-adapter.js
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/yui-utilities.js
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/ext-all.js
   jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/ext-config.js
   jifty/branches/virtual-models/plugins/ExtJS/share/web/templates/
   jifty/branches/virtual-models/plugins/ExtJS/t/
   jifty/branches/virtual-models/plugins/WikiToolbar/
   jifty/branches/virtual-models/plugins/WikiToolbar/Makefile.PL
   jifty/branches/virtual-models/plugins/WikiToolbar/doc/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar.pm
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Action/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Dispatcher.pm
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Model/
   jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Textarea.pm
   jifty/branches/virtual-models/plugins/WikiToolbar/share/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/po/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/bold.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/box.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/center.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/code.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/code1.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/empty.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/h1.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/h2.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/h3.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/italic.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/link.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/linkextern.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/new.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/ol.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/red.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/strike.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/tab.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/ul.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/underline.png   (contents, props changed)
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/js/
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/js/wikitoolbar.js
   jifty/branches/virtual-models/plugins/WikiToolbar/share/web/templates/
   jifty/branches/virtual-models/plugins/WikiToolbar/t/
   jifty/branches/virtual-models/plugins/WyzzEditor/
   jifty/branches/virtual-models/plugins/WyzzEditor/Makefile.PL
   jifty/branches/virtual-models/plugins/WyzzEditor/doc/
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor.pm
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/Dispatcher.pm
   jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/Textarea.pm
   jifty/branches/virtual-models/plugins/WyzzEditor/share/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/po/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/backcolor.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/bold.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/close.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/copy.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/cut.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/downsize.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/font.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/forecolor.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/headers.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/help.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/htmlmode.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/indent.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/inserthorizontalrule.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/insertimage.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/insertorderedlist.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/insertunorderedlist.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/italic.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifycenter.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifyfull.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifyleft.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifyright.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/link.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/outdent.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/paste.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/redo.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/removeformat.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/specialchar.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/strikethrough.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/subscript.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/superscript.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/underline.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/undo.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/upsize.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/wyzzicon.gif   (contents, props changed)
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/js/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/js/wyzz/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/js/wyzz.js
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/editarea.css
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/style.css
   jifty/branches/virtual-models/plugins/WyzzEditor/share/web/templates/
   jifty/branches/virtual-models/plugins/WyzzEditor/t/
   jifty/branches/virtual-models/share/po/ru.po
   jifty/branches/virtual-models/share/web/static/css/yui/menu/
   jifty/branches/virtual-models/share/web/static/css/yui/menu/map.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menu.css
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarodwn8_dim_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarodwn8_hov_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarodwn8_nrm_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarorght8_dim_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarorght8_hov_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarorght8_nrm_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuaroup8_dim_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuaroup8_nrm_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuchk8_dim_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuchk8_hov_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/menu/menuchk8_nrm_1.gif   (contents, props changed)
   jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabview.css
   jifty/branches/virtual-models/share/web/static/js/yui/element-beta.js
   jifty/branches/virtual-models/share/web/static/js/yui/menu.js
   jifty/branches/virtual-models/t/01-test-mechanize.t
   jifty/branches/virtual-models/t/10-utf8.t
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/CurrentUser.pm
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/11-current_user.t
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/12-i18n.t
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/12-signup.t
   jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/
   jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/base.pm
   jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/instance.pm
   jifty/branches/virtual-models/t/TestApp/t/15-template-subclass.t
Removed:
   jifty/branches/virtual-models/lib/Jifty/Plugin/AdminUI/View-not-yet.pm
   jifty/branches/virtual-models/lib/auto/
Modified:
   jifty/branches/virtual-models/   (props changed)
   jifty/branches/virtual-models/AUTHORS
   jifty/branches/virtual-models/Changelog
   jifty/branches/virtual-models/MANIFEST
   jifty/branches/virtual-models/META.yml
   jifty/branches/virtual-models/Makefile.PL
   jifty/branches/virtual-models/SIGNATURE
   jifty/branches/virtual-models/debian/changelog
   jifty/branches/virtual-models/debian/control
   jifty/branches/virtual-models/doc/talks/   (props changed)
   jifty/branches/virtual-models/inc/Module/Install.pm
   jifty/branches/virtual-models/inc/Module/Install/AutoInstall.pm
   jifty/branches/virtual-models/inc/Module/Install/Base.pm
   jifty/branches/virtual-models/inc/Module/Install/Can.pm
   jifty/branches/virtual-models/inc/Module/Install/Fetch.pm
   jifty/branches/virtual-models/inc/Module/Install/Include.pm
   jifty/branches/virtual-models/inc/Module/Install/Makefile.pm
   jifty/branches/virtual-models/inc/Module/Install/Metadata.pm
   jifty/branches/virtual-models/inc/Module/Install/Scripts.pm
   jifty/branches/virtual-models/inc/Module/Install/Share.pm
   jifty/branches/virtual-models/inc/Module/Install/Win32.pm
   jifty/branches/virtual-models/inc/Module/Install/WriteAll.pm
   jifty/branches/virtual-models/lib/Jifty.pm
   jifty/branches/virtual-models/lib/Jifty/Action.pm
   jifty/branches/virtual-models/lib/Jifty/Action/Record.pm
   jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm
   jifty/branches/virtual-models/lib/Jifty/Config.pm
   jifty/branches/virtual-models/lib/Jifty/CurrentUser.pm
   jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Handle.pm
   jifty/branches/virtual-models/lib/Jifty/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/I18N.pm
   jifty/branches/virtual-models/lib/Jifty/JSON.pm
   jifty/branches/virtual-models/lib/Jifty/LetMe.pm
   jifty/branches/virtual-models/lib/Jifty/Manual/AccessControl.pod
   jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod
   jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/View.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/ErrorTemplates/View.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/View.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/User/Mixin/Model/User.pm
   jifty/branches/virtual-models/lib/Jifty/Record.pm
   jifty/branches/virtual-models/lib/Jifty/Script/FastCGI.pm
   jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm
   jifty/branches/virtual-models/lib/Jifty/Subs/Render.pm
   jifty/branches/virtual-models/lib/Jifty/Test.pm
   jifty/branches/virtual-models/lib/Jifty/Test/WWW/Mechanize.pm
   jifty/branches/virtual-models/lib/Jifty/TestServer.pm
   jifty/branches/virtual-models/lib/Jifty/Upgrade.pm
   jifty/branches/virtual-models/lib/Jifty/Util.pm
   jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm
   jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/Web.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Form.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Form/Element.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Form/Field.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm
   jifty/branches/virtual-models/lib/Jifty/Web/PageRegion.pm
   jifty/branches/virtual-models/plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action/FileEditor.pm
   jifty/branches/virtual-models/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/content.html
   jifty/branches/virtual-models/share/po/en.po
   jifty/branches/virtual-models/share/po/fr.po
   jifty/branches/virtual-models/share/po/ja.po
   jifty/branches/virtual-models/share/po/zh_cn.po
   jifty/branches/virtual-models/share/po/zh_tw.po
   jifty/branches/virtual-models/share/web/static/css/forms.css
   jifty/branches/virtual-models/share/web/static/css/main.css
   jifty/branches/virtual-models/share/web/static/css/yui/calendar/calendar.css
   jifty/branches/virtual-models/share/web/static/css/yui/tabview/border_tabs.css
   jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabs.css
   jifty/branches/virtual-models/share/web/static/js/yui/calendar.js
   jifty/branches/virtual-models/share/web/static/js/yui/container.js
   jifty/branches/virtual-models/share/web/static/js/yui/dom.js
   jifty/branches/virtual-models/share/web/static/js/yui/event.js
   jifty/branches/virtual-models/share/web/static/js/yui/tabview.js
   jifty/branches/virtual-models/share/web/static/js/yui/yahoo.js
   jifty/branches/virtual-models/share/web/templates/_elements/nav
   jifty/branches/virtual-models/t/Mapper/t/02-api.t
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/etc/config.yml
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Dispatcher.pm
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model/User.pm
   jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/00-model-User.t
   jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm

Log:
* Merge down from trunk


r53594 at pinglin (orig r3012):  jesse | 2007-03-17 15:16:25 -0400
  r53592 at pinglin:  jesse | 2007-03-17 15:15:48 -0400
  * minor cleanup based on attempted use of the login/signup plugin
 
 r53596 at pinglin (orig r3014):  dpavlin | 2007-03-17 20:45:52 -0400
 extracted dump_rules into DumpDispatcher plugin
 r53620 at pinglin (orig r3025):  jesse | 2007-03-18 17:44:30 -0400
  r53619 at pinglin:  jesse | 2007-03-18 17:44:06 -0400
  * When you rest a lost password, email address is implicitly confirmed
 
 r53623 at pinglin (orig r3026):  jesse | 2007-03-18 22:03:24 -0400
  r53621 at pinglin:  jesse | 2007-03-18 21:35:20 -0400
  * Added the ability to have a return button that looks like a submit button on a form.
 
 r53624 at pinglin (orig r3027):  jesse | 2007-03-18 22:03:33 -0400
  r53622 at pinglin:  jesse | 2007-03-18 21:37:50 -0400
  * return from tangents for login, signup, password reminders
 
 r53633 at pinglin (orig r3028):  jesse | 2007-03-19 13:31:14 -0400
  r53632 at pinglin:  jesse | 2007-03-19 13:27:23 -0400
      From:     evdb at ecclestoad.co.uk
      Subject:    Re: [jifty-devel] 'smart_tag_wrapper' to make creating smarter tags easier
      Date:   March 19, 2007 11:36:20 AM EDT
      To:       jifty-devel at lists.jifty.org
      Reply-To:     jifty-devel at lists.jifty.org
  
  On 19/03/07, Jesse Vincent <jesse at bestpractical.com> wrote:
  I needed this tonight. Wanna make it go? ;)
  On Mar 16, 2007, at 5:26 AM, Edmund von der Burg wrote:
  
  I'd love to make it go but can't at the moment as I am not able to
  connect to the net this week (except via a local libary machine that
  is so crippled that it does not count).
  
  The code at the start of this thread for 'form' works for me, please
  add it as you see fit :)
  
  Cheers,
   Edmund
  
  > Hello,
  >
  > I've just committed code to Template::Declare that should make it
  > easier to create smarter wrappers in the templates - for example the
  > 'form' wrapper. Please see the diff for the details.
  >
  >  http://svn.jifty.org/index.cgi/jifty/revision/?rev=2989
  >
  > Using this the 'form' sub in J::V::Declare::Helpers would become:
  >
  > {
  >    no warnings qw/redefine/;
  >    sub form (&) {
  >        my $code = shift;
  >
  >        smart_tag_wrapper {
  >          outs_raw( Jifty->web->form->start(@_) );
  >          $code->();
  >          outs_raw( Jifty->web->form->end );
  >          return '';
  >        };
  >    }
  > }
  >
  >
  > you could then call it like this (not tested properly):
  >
  > my $action = ...setup_action..;
  > with( call => $next, name => "loginbox" ),
  
 
 r53635 at pinglin (orig r3029):  jesse | 2007-03-19 17:06:45 -0400
  r53634 at pinglin:  jesse | 2007-03-19 16:56:05 -0400
   * Don't create a new config object every time we look at the db version
 
 r53646 at pinglin (orig r3030):  sterling | 2007-03-19 17:07:37 -0400
  r4119 at riddle:  andrew | 2007-03-19 16:06:22 -0500
  Modified submit_html_ok to make it behave like the documentation says it should.
 
 r53647 at pinglin (orig r3031):  falcone | 2007-03-19 17:34:51 -0400
  r17465 at ketch:  falcone | 2007-03-19 17:32:42 -0400
  * don't load up PodSimple and other friends unless you've
    actually enabled AdminMode and brought OnlineDocs
    into the picture
 
 r53648 at pinglin (orig r3032):  jesse | 2007-03-19 21:30:44 -0400
  r53640 at pinglin:  jesse | 2007-03-19 21:29:02 -0400
  * When running coverage, don't use Class::Accessor::Named as it uses Hook::LexWrap
 
 r53740 at pinglin (orig r3033):  falcone | 2007-03-19 23:04:35 -0400
  r17477 at ketch:  falcone | 2007-03-19 22:59:47 -0400
  * remove duplicated line
 
 r53741 at pinglin (orig r3034):  falcone | 2007-03-19 23:04:41 -0400
  r17478 at ketch:  falcone | 2007-03-19 23:00:26 -0400
  * Administration and Online docs tabs are set in Jifty/Plugin/*/Dispatcher.pm
 
 r53742 at pinglin (orig r3035):  falcone | 2007-03-19 23:05:15 -0400
  r17479 at ketch:  falcone | 2007-03-19 23:02:13 -0400
  * don't require a bunch of unused modules that don't trickle to the templates
  * don't set the Home tab twice
  * use Pod::Simple::HTML where we need it
 
 r53743 at pinglin (orig r3036):  sterling | 2007-03-20 10:38:43 -0400
  r4122 at riddle:  andrew | 2007-03-20 09:31:17 -0500
  Added a basic test stub for Jifty::Test::WWW::Mechanize.
 
 r53746 at pinglin (orig r3037):  jesse | 2007-03-20 20:58:57 -0400
  r53745 at pinglin:  jesse | 2007-03-20 20:57:00 -0400
   * Switch config to automatic instantiation
 
 r53748 at pinglin (orig r3038):  jesse | 2007-03-20 21:05:02 -0400
  r53747 at pinglin:  jesse | 2007-03-20 21:04:44 -0400
  * When you break an API, it breaks tests.
  
 
 r53763 at pinglin (orig r3039):  alexmv | 2007-03-20 22:55:18 -0400
  r17706 at zoq-fot-pik:  chmrr | 2007-03-06 17:06:29 -0500
   * Log::Log4perl::Appender::String (used in tests) was only added in
     1.02; require at least that
 
 r53764 at pinglin (orig r3040):  alexmv | 2007-03-20 22:55:58 -0400
  r18076 at zoq-fot-pik:  chmrr | 2007-03-20 22:55:02 -0400
   * Use Jifty->app_class in a couple more places
 
 r53765 at pinglin (orig r3041):  sterling | 2007-03-21 08:38:25 -0400
  r4160 at riddle:  andrew | 2007-03-21 07:38:09 -0500
  Updated documentation to reflect that fact that submit_html_ok() takes no arguments.
 
 r53767 at pinglin (orig r3042):  jesse | 2007-03-21 14:55:00 -0400
  r53762 at pinglin:  jesse | 2007-03-21 14:52:07 -0400
  * started outline of yapc::asia talk
  
 
 r53772 at pinglin (orig r3043):  jesse | 2007-03-21 15:39:43 -0400
  r53770 at pinglin:  jesse | 2007-03-21 15:39:03 -0400
  * Better plugin I18N
  
  Alexey Grebenschikov wrote:
  Plugin paths don't need to convert because File::ShareDir::module_dir
  always returns an absolute path. I have added also modification checking
  to the Jifty::I18N::refresh for plugin po files. 
  
  
  
 
 r53773 at pinglin (orig r3044):  jesse | 2007-03-21 15:39:51 -0400
  r53771 at pinglin:  jesse | 2007-03-21 15:39:16 -0400
  * Make sure test coverage copes with new jifty->config 
 
 r53786 at pinglin (orig r3045):  clkao | 2007-03-22 14:16:42 -0400
 The value of field should not be localised.
 r53789 at pinglin (orig r3046):  jesse | 2007-03-22 21:10:32 -0400
  r53788 at pinglin:  jesse | 2007-03-22 21:09:27 -0400
  * Refactor the I18N plugin stuff to not fail tests.
 
 r53800 at pinglin (orig r3047):  nelhage | 2007-03-22 21:18:06 -0400
 We load the config on demand now, so it always exists. Test for
 classloader existence, instead of config existence, to tell whether or
 not we need to Jifty->new.
 
 r53802 at pinglin (orig r3049):  jesse | 2007-03-23 19:59:02 -0400
  r53798 at pinglin:  jesse | 2007-03-23 19:57:04 -0400
  * skeleton for clkao to fill in ;)
 
 r53843 at pinglin (orig r3051):  clkao | 2007-03-23 22:05:42 -0400
 Make render_region resolve relative template in current context.
 r53845 at pinglin (orig r3053):  clkao | 2007-03-23 22:30:15 -0400
 tests for view subclasses.
 r53846 at pinglin (orig r3054):  clkao | 2007-03-23 22:33:23 -0400
 failing tests for view subclasses.
 r53847 at pinglin (orig r3055):  clkao | 2007-03-23 23:11:37 -0400
 tidy up.
 r53848 at pinglin (orig r3056):  clkao | 2007-03-24 11:40:53 -0400
 bypass $self for  page content callbacks.
 r54202 at pinglin (orig r3058):  jesse | 2007-03-25 11:24:07 -0400
  r53799 at pinglin:  jesse | 2007-03-23 19:58:39 -0400
  * Can't just check to see if the config exists to decide whether to initialze the Jifty
 
 r54203 at pinglin (orig r3059):  jesse | 2007-03-25 11:25:01 -0400
  r53805 at pinglin:  jesse | 2007-03-24 20:00:04 -0400
  * added back the div id 'content' for parity with old jifty templates 
 
 r54209 at pinglin (orig r3060):  jesse | 2007-03-25 22:46:03 -0400
  r54207 at pinglin:  jesse | 2007-03-25 15:49:17 -0700
  * Added a 'None' session type for when your application doesn't need sessions
 
 r54243 at pinglin (orig r3061):  clkao | 2007-03-26 08:59:38 -0400
 fix a bracket that breaks is::title.
 r54244 at pinglin (orig r3062):  clkao | 2007-03-26 09:12:51 -0400
 Move the h1 in default wrapper to a overridable template.
 r54245 at pinglin (orig r3063):  nelhage | 2007-03-26 16:31:29 -0400
 Make CurrentUser->new work as a method on an instance, so that
 as_superuser works.
 
 r54396 at pinglin (orig r3075):  jesse | 2007-03-31 21:27:37 -0400
  r54395 at pinglin:  jesse | 2007-03-31 18:26:46 -0700
  * helpers improvements for T::D
 
 r54402 at pinglin (orig r3077):  jesse | 2007-03-31 22:14:19 -0400
  r54401 at pinglin:  jesse | 2007-03-31 19:13:28 -0700
   * Notes on the early genesis of JDBI schema
 
 r54405 at pinglin (orig r3078):  dpavlin | 2007-04-01 08:41:39 -0400
 fix handling of multi-line data when encoded in JSON -- they should never
 wrap over multiple lines in generated output
 r54414 at pinglin (orig r3079):  dpavlin | 2007-04-01 14:32:15 -0400
 remove extra skeleton files, configuration example in pod
 r54415 at pinglin (orig r3080):  trs | 2007-04-02 01:22:07 -0400
  r20560 at zot:  tom | 2007-04-02 01:21:31 -0400
  * Make =head2 sections consistently titled
  * Add section on using models/actions outside of a Jifty app
 
 r54416 at pinglin (orig r3081):  jesse | 2007-04-03 02:25:58 -0400
  r54413 at dhcp207:  jesse | 2007-04-03 15:25:32 +0900
  * Next slides draft (and the tool to render them)
 
 r54419 at pinglin (orig r3083):  jesse | 2007-04-03 03:52:07 -0400
  r54417 at dhcp207:  jesse | 2007-04-03 16:51:42 +0900
   * ok. mostly ready
 
 r54421 at pinglin (orig r3084):  jesse | 2007-04-03 04:23:03 -0400
  r54420 at dhcp207:  jesse | 2007-04-03 17:22:40 +0900
  * tidy
 
 r54423 at pinglin (orig r3085):  jesse | 2007-04-03 04:45:09 -0400
  r54422 at dhcp207:  jesse | 2007-04-03 17:44:46 +0900
   intro slides
 
 r54425 at pinglin (orig r3086):  audreyt | 2007-04-03 04:47:07 -0400
 * dedebugbug.
 r54427 at pinglin (orig r3087):  jesse | 2007-04-03 05:10:58 -0400
  r54424 at dhcp207:  jesse | 2007-04-03 18:09:49 +0900
  * added a "SkipAccessControl" framework directive
 
 r54428 at pinglin (orig r3088):  audreyt | 2007-04-03 05:50:52 -0400
 * Jifty::Plugin - Authentication::Password now auto-loads LetMe and User.
 r54431 at pinglin (orig r3089):  jesse | 2007-04-03 06:12:52 -0400
  r54430 at dhcp207:  jesse | 2007-04-03 19:11:02 +0900
  * pod fixes
  * update tests to take advantage of audrey's new feature (plugin deps)
  
 
 r54433 at pinglin (orig r3090):  jesse | 2007-04-03 21:31:57 -0400
  r54432 at pinglin-2:  jesse | 2007-04-04 10:10:29 +0900
   * More tweaking
  
 
 r54436 at pinglin (orig r3091):  jesse | 2007-04-03 22:29:30 -0400
  r54434 at pinglin-2:  jesse | 2007-04-04 11:08:47 +0900
  * tweaky
 
 r54437 at pinglin (orig r3092):  jesse | 2007-04-03 22:30:07 -0400
  r54435 at pinglin-2:  jesse | 2007-04-04 11:29:04 +0900
  more slides
 
 r54439 at pinglin (orig r3093):  jesse | 2007-04-04 01:05:43 -0400
  r54438 at pinglin-2:  jesse | 2007-04-04 14:04:04 +0900
  * Slides system now has a presenter view
 
 r54441 at pinglin (orig r3094):  jesse | 2007-04-04 01:59:46 -0400
  r54440 at pinglin-2:  jesse | 2007-04-04 14:56:43 +0900
  * Autoopen the presenter tools
  
 
 r54444 at pinglin (orig r3095):  hlb | 2007-04-04 02:03:58 -0400
 * fix "open" class in menu - active menu item doesn't imply current open item
 
 r54445 at pinglin (orig r3096):  audreyt | 2007-04-04 14:18:24 -0400
 * Snapshot of doxory slides.
 r54448 at pinglin (orig r3097):  alexmv | 2007-04-04 19:53:33 -0400
  r18733 at zoq-fot-pik:  chmrr | 2007-04-04 19:53:06 -0400
   * Typo fix in example in POD
   * Remove old, unused empty directory
 
 r54480 at pinglin (orig r3098):  audreyt | 2007-04-05 01:28:43 -0400
 * YAPC::Asia 2007, "Jifty Now!", slides and demo.
 r54491 at pinglin (orig r3099):  audreyt | 2007-04-05 01:35:04 -0400
 * Add PDF version of the slides.
 r54530 at pinglin (orig r3103):  jesse | 2007-04-06 12:08:59 -0400
  r54442 at dhcp207:  jesse | 2007-04-04 17:50:57 +0900
  tweaking
  
 
 r54531 at pinglin (orig r3104):  jesse | 2007-04-06 12:09:18 -0400
  r54443 at dhcp207:  jesse | 2007-04-04 23:33:32 +0900
  * now with support for I18N (japanese)
 
 r54532 at pinglin (orig r3105):  jesse | 2007-04-06 12:10:25 -0400
  r54521 at dhcp207:  jesse | 2007-04-06 21:37:18 +0900
  * let the "email confirmed" field be visible from the admin ui
 
 r54533 at pinglin (orig r3106):  jesse | 2007-04-06 12:10:56 -0400
  r54522 at dhcp207:  jesse | 2007-04-06 21:37:27 +0900
  * Talk updates
 
 r54534 at pinglin (orig r3107):  jesse | 2007-04-06 12:11:14 -0400
  r54527 at dhcp207:  jesse | 2007-04-07 00:33:45 +0900
  * Refactoring to support more template engines 
  
  
 
 r54535 at pinglin (orig r3108):  jesse | 2007-04-06 12:11:45 -0400
  r54528 at dhcp207:  jesse | 2007-04-07 00:49:58 +0900
   *more refactorign to extract templating stuff
 
 r54536 at pinglin (orig r3109):  jesse | 2007-04-06 12:12:03 -0400
  r54529 at dhcp207:  jesse | 2007-04-07 01:08:43 +0900
  * Refactor and extract
 
 r54554 at pinglin (orig r3110):  jesse | 2007-04-07 00:22:29 -0400
  r54553 at dhcp207:  jesse | 2007-04-07 00:22:09 -0400
  * Preforking server support for Jifty::Server
 
 r54717 at pinglin (orig r3111):  ishigaki | 2007-04-08 10:18:58 -0400
 added Japanese translation of Jesse's talk at YAPC::Asia 2007
 r54718 at pinglin (orig r3112):  audreyt | 2007-04-08 11:37:06 -0400
 * present-slides: Avoid a "splitting to @_ is deprecated" warning.
 r54719 at pinglin (orig r3113):  trs | 2007-04-08 15:17:53 -0400
  r20646 at zot:  tom | 2007-04-08 15:17:04 -0400
  Add doc and prefork dependency so the doc and dep tests pass
 
 r54720 at pinglin (orig r3114):  dpavlin | 2007-04-08 15:49:35 -0400
 added audryt Doxory from doc/talks/yapcasia2007-doxory.pdf
 r54721 at pinglin (orig r3115):  dpavlin | 2007-04-08 15:59:08 -0400
 Turn on AdminMode and don't require login for it in dispatcher
 r54814 at pinglin (orig r3117):  evdb | 2007-04-11 11:50:41 -0400
 Allow '->superuser' to be both an object and class method.
 
 r54815 at pinglin (orig r3118):  hlb | 2007-04-12 03:32:44 -0400
 * Upgraded YUI to 2.2.1
   * NOTICE: if you are using yui tabview, 
     please use tabview.css instead of tabs.css
 * Added yui/element-beta.js and yui/menu.js in Web.pm
 
 r54816 at pinglin (orig r3119):  hlb | 2007-04-12 03:36:00 -0400
 * Added render_as_yui_menubar in Menu.pm
 
 r54817 at pinglin (orig r3120):  audreyt | 2007-04-12 06:54:33 -0400
 * Jifty::Plugin::REST::Dispatcher - Gugod pointed out that we don't need to
   stringify() the object-to-data output, because (esp for nested structures)
   it's far more convenient to have the $accept-specific formatter (e.g.
   YAML or JSON) to render it.
 r54818 at pinglin (orig r3121):  clkao | 2007-04-13 08:16:55 -0400
 render_region should have default empty path.
 r55429 at pinglin (orig r3122):  falcone | 2007-04-13 17:04:00 -0400
  r18017 at ketch:  falcone | 2007-04-13 17:02:35 -0400
  * WWW::Mechanize 1.22 removed the form method.  
    thanks to hdp for noticing/poking
 
 r55430 at pinglin (orig r3123):  audreyt | 2007-04-13 19:54:24 -0400
 * zh-tw L10N for authen/passwd/user plugins.
 r55431 at pinglin (orig r3124):  audreyt | 2007-04-13 19:55:39 -0400
 * Doxory L10N.
 r55447 at pinglin (orig r3130):  jesse | 2007-04-15 12:07:18 -0400
  r55444 at pinglin:  jesse | 2007-04-15 12:05:49 -0400
  * Notes on distributed operation (mostly based on reading papers about Xerox PARC
 
 r55448 at pinglin (orig r3131):  jesse | 2007-04-15 12:07:40 -0400
  r55445 at pinglin:  jesse | 2007-04-15 12:06:01 -0400
   * Start of the oscon 2007 talk 
 
 r55449 at pinglin (orig r3132):  jesse | 2007-04-15 12:07:49 -0400
  r55446 at pinglin:  jesse | 2007-04-15 12:06:10 -0400
  * Todoifying tests for release
 
 r55451 at pinglin (orig r3133):  jesse | 2007-04-15 12:32:05 -0400
  r55450 at pinglin:  jesse | 2007-04-15 12:31:42 -0400
  * Some of our 'optional' deps are required for Jifty's tests. Thanks to Nicholas Clark
 
 r55455 at pinglin (orig r3134):  jesse | 2007-04-15 12:55:47 -0400
  r55452 at pinglin:  jesse | 2007-04-15 12:54:47 -0400
  * Require current T::D
  r55453 at pinglin:  jesse | 2007-04-15 12:54:59 -0400
  * Bump for release
  r55454 at pinglin:  jesse | 2007-04-15 12:55:21 -0400
  * Require new Jifty::DBI
 
 r55458 at pinglin (orig r3135):  jesse | 2007-04-15 13:02:55 -0400
  r55456 at pinglin:  jesse | 2007-04-15 13:01:48 -0400
   manifest update
 
 r55459 at pinglin (orig r3136):  jesse | 2007-04-15 13:03:06 -0400
  r55457 at pinglin:  jesse | 2007-04-15 13:02:08 -0400
   * signature update
 
 r55485 at pinglin (orig r3139):  yves | 2007-04-15 17:05:12 -0400
 changes for debian packages 
 
 r55487 at pinglin (orig r3141):  clkao | 2007-04-16 08:36:13 -0400
 * no_index for examples/.
 * remove implicit no_index.
 
 r55488 at pinglin (orig r3142):  clkao | 2007-04-16 08:41:49 -0400
 Update MI and META.yml.
 r55489 at pinglin (orig r3143):  clkao | 2007-04-16 08:46:04 -0400
 Missed share/ in no_index.
 r55592 at pinglin (orig r3144):  hlb | 2007-04-16 13:59:52 -0400
 * Jifty::Plugins::ExtJS - it contains necessary files to run Ext JavaScript
   library. It comes with Ext v1.0.
 
 r55598 at pinglin (orig r3145):  yves | 2007-04-16 16:52:03 -0400
 some failing tests on new plugin password, for me test 9 is ok : object id is good, but tests 10 to 14 fail, current user can't read his name mail or mygroup
 
 r55599 at pinglin (orig r3146):  yves | 2007-04-16 17:13:31 -0400
 current_user_can must be set
 
 r55601 at pinglin (orig r3147):  jesse | 2007-04-17 02:57:40 -0400
  r55589 at apc:  jesse | 2007-04-16 21:11:21 +0200
  * Auth::Password plugin: Quiet down warning about a nonexistent class in @ISA by defering that until ->new time.
 
 r55602 at pinglin (orig r3148):  jesse | 2007-04-17 02:58:04 -0400
  r55590 at apc:  jesse | 2007-04-16 21:15:39 +0200
  * Quiet down falsely failing todo tests in template sublcassing.
 
 r55603 at pinglin (orig r3149):  jesse | 2007-04-17 02:58:13 -0400
  r55591 at apc:  jesse | 2007-04-16 21:23:28 +0200
  
  * poorly  started adminui port to TD was broken and caused test warnings. and was unused
 
 r55604 at pinglin (orig r3150):  jesse | 2007-04-17 02:58:41 -0400
  r55594 at apc:  jesse | 2007-04-16 22:17:03 +0200
   * 0.70416
 
 r55644 at pinglin (orig r3151):  yves | 2007-04-17 04:00:17 -0400
 debian stuff, fr.po update
 
 r55645 at pinglin (orig r3152):  yves | 2007-04-17 05:01:37 -0400
 change manual for access control with user and authentication::password plugins
 
 r55646 at pinglin (orig r3153):  yves | 2007-04-17 16:04:10 -0400
 failling test on i18n and T::D authentication plugin
 
 r55754 at pinglin (orig r3154):  evdb | 2007-04-18 11:40:13 -0400
 Created a method that can be over-ridden for custom test database setup
 
 r55765 at pinglin (orig r3155):  jesse | 2007-04-19 12:22:54 -0400
  r55756 at pinglin:  jesse | 2007-04-18 20:58:46 -0400
  Typo spotted by semifor
 
 r55766 at pinglin (orig r3156):  jesse | 2007-04-19 12:22:59 -0400
  r55764 at pinglin:  jesse | 2007-04-19 12:21:41 -0400
  * Doc updates for Jifty::ClassLoader -- David Good <dgood at willingminds.com>
 
 r55767 at pinglin (orig r3157):  semifor | 2007-04-19 13:28:12 -0400
 exceedingly trivial fix (semantic noop), but it's a start
 
 r55768 at pinglin (orig r3158):  audreyt | 2007-04-19 15:24:05 -0400
 * Revert the bogus r3147 as it kills Doxory example.  (reported by semifor++)
 r55770 at pinglin (orig r3159):  audreyt | 2007-04-19 15:33:13 -0400
 * Jifty::Module::Pluggable - Silence the @ISA warnings. 
 r55772 at pinglin (orig r3160):  semifor | 2007-04-19 18:31:47 -0400
 added regression test for bug fix (by autreyt) in rev 3158,
 Jifty::Plugin::Authentication::Password::Action::Signup
 
 r55829 at pinglin (orig r3161):  audreyt | 2007-04-20 01:36:55 -0400
 * Jifty::Upgrade - Defensive programming against tables that did
   not have "create table" in its schema for SQLite column renaming.
   (This really shouldn't happen.)
 r55831 at pinglin (orig r3163):  sterling | 2007-04-20 16:43:02 -0400
  r4564 at riddle:  andrew | 2007-04-20 15:42:21 -0500
  Added duck typing to the Jifty::Handle constructor to prevent difficult to trace error messages when the driver name is mispelt or fails to load.
 
 r55832 at pinglin (orig r3164):  jesse | 2007-04-22 19:33:50 -0400
  r55807 at pinglin:  jesse | 2007-04-22 19:19:36 -0400
  * More debugging info for broken letmes
 
 r55833 at pinglin (orig r3165):  jesse | 2007-04-22 19:33:59 -0400
  r55808 at pinglin:  jesse | 2007-04-22 19:19:56 -0400
  * Better "password reset" behaviour  
 
 r56079 at pinglin (orig r3166):  hlb | 2007-04-24 15:04:57 -0400
 * Added class="active" for current menu item in render_as_yui_menubar
 
 r56080 at pinglin (orig r3167):  audreyt | 2007-04-26 08:44:15 -0400
 * ErrorTemplates - Use absolute paths as relative ones in mixined templates
   does not appear to work yet.
 r56081 at pinglin (orig r3168):  audreyt | 2007-04-26 08:59:34 -0400
 * Jifty::Web::Form::Element - All direct-javascript-injection into HTML 
   needs to be properly HTML escaped.  This fixed the case where there are
   e.g. double quotes and ampersands in prompt()/keybinding data, as well
   as make the bogus-Unicode-double-decoding bug go away in IE.
 
 * Also, prompt() support was broken in IE as clicking "cancel" will still
   submit the action anyway; an "Event.stop(event);" corrected this. 
 
 r56085 at pinglin (orig r3170):  jesse | 2007-04-27 15:39:49 -0400
  r55834 at pinglin:  jesse | 2007-04-22 21:05:00 -0400
  * 0.70422 releng
 
 r56086 at pinglin (orig r3171):  jesse | 2007-04-27 15:42:32 -0400
  r56083 at pinglin:  jesse | 2007-04-27 15:39:25 -0400
  * remove debugging output
 
 r56151 at pinglin (orig r3172):  gugod | 2007-04-29 05:11:35 -0400
 This module is for rendering a collection of input fields at once
 as a single widget. The major goal is to let developer say like:
 
   column bars =>
     refers_to "My::Model::BarCollection",
     render as "Collection"
     availables are defer {
         retrieve_some_bars()
     };
 
 in their model class, and it'll just display a nice form to input
 the value for a list of available bars.
 
 r56152 at pinglin (orig r3173):  jesse | 2007-04-30 09:39:25 -0400
  r56108 at pinglin:  jesse | 2007-04-27 20:14:23 -0400
  * More refactoring toward making view handlers plugins
 
 r56153 at pinglin (orig r3174):  jesse | 2007-04-30 09:39:36 -0400
  r56109 at pinglin:  jesse | 2007-04-27 20:14:41 -0400
  * quiet some warnings
 
 r56154 at pinglin (orig r3175):  jesse | 2007-04-30 09:39:45 -0400
  r56110 at pinglin:  jesse | 2007-04-27 20:15:05 -0400
  * don't index plugins' test directories
 
 r56155 at pinglin (orig r3176):  jesse | 2007-04-30 09:40:02 -0400
  r56150 at pinglin:  jesse | 2007-04-30 09:23:11 -0400
  * More refactoring in support of adding new view handlers.
 
 r56171 at pinglin (orig r3177):  yves | 2007-04-30 11:55:39 -0400
 add the ability to have some code before a javascript click :
    onclick => [ { beforeclick => "<somecode>;" }, { args => ...
 
 r56172 at pinglin (orig r3178):  jesse | 2007-04-30 16:10:33 -0400
  r56170 at pinglin:  jesse | 2007-04-30 16:10:24 -0400
  * initial environment that makes fastcgi work got deleted
 
 r56178 at pinglin (orig r3179):  jesse | 2007-04-30 16:31:31 -0400
  r56177 at pinglin:  jesse | 2007-04-30 16:31:23 -0400
   * utf8::downgrade() content about to be sent out from a Template::Declare template. THIS WANTS A COMMENT FROM AUDREYT OR MIYAGAWA
  
 
 r56180 at pinglin (orig r3180):  jesse | 2007-04-30 16:50:05 -0400
  r56179 at pinglin:  jesse | 2007-04-30 16:49:58 -0400
  * Miyagawa++ points out that 'use utf8' is wrong.
 
 r56266 at pinglin (orig r3181):  yves | 2007-04-30 17:56:18 -0400
 plugin to use Wyzz online wyziwig editor to render textaera for test and comments
 
 r56267 at pinglin (orig r3182):  ruz | 2007-04-30 18:42:44 -0400
 * utf8::downgrade doesn't like strings as FAIL_OK, only integers, 1 is not that
   cool as 'FAILURE IS OK', but works
 r56268 at pinglin (orig r3183):  ruz | 2007-04-30 21:26:58 -0400
 * linked POD++
 r56269 at pinglin (orig r3184):  ruz | 2007-04-30 21:27:42 -0400
 * my dict has no word signup, but has 'sign up'
 r56270 at pinglin (orig r3185):  ruz | 2007-04-30 21:28:25 -0400
 * delete trailing space to avoid translating the same string twice
 r56271 at pinglin (orig r3186):  ruz | 2007-04-30 21:29:32 -0400
 * two very similar strings in one place, use the same, easier for translation
 r56272 at pinglin (orig r3187):  ruz | 2007-04-30 21:30:08 -0400
 * ru.po
 r56292 at pinglin (orig r3191):  yves | 2007-05-02 04:50:44 -0400
 plugin to add a wiki toolbar to textarea
 
 r56718 at pinglin (orig r3193):  clkao | 2007-05-04 06:49:18 -0400
 fast test support: truncate tables rather than recreating database
 when JIFTY_FAST_TEST is specified.
 
 r56733 at pinglin (orig r3194):  ruz | 2007-05-05 09:15:04 -0400
 * drop undef warning
 r56735 at pinglin (orig r3196):  ruz | 2007-05-05 21:43:19 -0400
 * we need bytes in escape_uri then 'use bytes'
 * resulting string is always valid ascii string,
   so we shouldn't forcibly set utf flag
 r56736 at pinglin (orig r3197):  ruz | 2007-05-05 21:51:06 -0400
 escape_utf8
 * don't use bytes just escape things doesn't matter if it's
   flagged string or not, perl must do the right thing.
 * don't localize ref, use it directly, afaik smaller
   memory footprint
 r56737 at pinglin (orig r3198):  yves | 2007-05-06 04:24:07 -0400
 a failing test about utf8 when using T::D
 
 r56738 at pinglin (orig r3199):  dpavlin | 2007-05-06 18:29:38 -0400
 fix pod typo
 r56739 at pinglin (orig r3200):  ruz | 2007-05-06 19:58:08 -0400
 * add tests for UTF-8 related things
 r56740 at pinglin (orig r3201):  ruz | 2007-05-06 20:00:54 -0400
 * add docs to escape_uri
 * fix it in the way need it to work, it's escape_uri_utf8. there is no
   way to escape binary and text scalars in one sub, we need the latter.
 r56741 at pinglin (orig r3202):  ruz | 2007-05-06 20:05:57 -0400
 * small update to ru.po
 r56742 at pinglin (orig r3203):  ruz | 2007-05-06 20:21:19 -0400
 * utf8::downgrade converts to octets only if string had been upgraded, what is not
   always true for 'perl strings'
 r56743 at pinglin (orig r3204):  ruz | 2007-05-06 21:20:01 -0400
 * revert the latest change unless we fix all utf8 stack
 r56744 at pinglin (orig r3205):  ruz | 2007-05-07 11:23:34 -0400
 * delete not used var
 r56745 at pinglin (orig r3206):  ruz | 2007-05-07 11:27:31 -0400
 * we shouldn't silence utf8 warnings
 r56746 at pinglin (orig r3207):  ruz | 2007-05-07 11:33:48 -0400
 * indent, minor
 r56747 at pinglin (orig r3208):  ruz | 2007-05-07 12:35:58 -0400
 to sanity through insanity
 * control mode of output handles, if content type has charset defined
   then we set :encoding(<charset>) output layer (or :utf8), otherwise
   binary
 * regions are special as we print out them into STDOUT, but sometimes
   need them as a string. We localize STDOUT and get data, however because
   of the above canonicalization we get octets or binary, so we check
   again the current content type. If the type contains charset definition
   then we decode octets back into perl string(in terms of perl unicode support),
   otherwise we leave things as is.
 
 jifty is sane when apps' developers are sane
 * never use 'bytes' pragma
 * avoid using 'encoding' pragma
 * use perl strings in jifty
 ** when you get a text data from external sources then Encode::decode it
 * set output encoding with $r->content_type('type/subtype; charset=XXX')
 ** by default it's UTF-8
 ** you can use cp1251 (or other) and things should work, user will get
    data in cp1251 and browser should display it right
 ** don't Encode::encode things before output
 
 everybody have own critirea of sanity
 * if you think that something is wrong then add tests to jifty 
 
   


Modified: jifty/branches/virtual-models/AUTHORS
==============================================================================
--- jifty/branches/virtual-models/AUTHORS	(original)
+++ jifty/branches/virtual-models/AUTHORS	Mon May  7 16:28:32 2007
@@ -26,3 +26,4 @@
 Edgar Whipple <jifty at misterwhipple.com>
 Christian Ternus <ternus at mit.edu>
 David Brunton <dbrunton at yahoo.com>
+Marc Mims <marc at questright.com>

Modified: jifty/branches/virtual-models/Changelog
==============================================================================
--- jifty/branches/virtual-models/Changelog	(original)
+++ jifty/branches/virtual-models/Changelog	Mon May  7 16:28:32 2007
@@ -1,3 +1,261 @@
+Jifty 0.70422
+
+[Password Authentication plugin]
+
+* Better "password reset" behaviour  
+* added regression test for bug fix in Jifty::Plugin::Authentication::Password::Action::Signup
+* change manual for access control with user and authentication::password plugins
+* Revert the bogus warning silencing in 0.70416 as it kills Doxory example.  
+  (reported by semifor++)
+ 
+[Core]
+
+* More debugging info for broken letmes
+* Added duck typing to the Jifty::Handle constructor to prevent difficult 
+  to trace error messages when the driver name is mispelt or fails to load.
+* Jifty::Upgrade - Defensive programming against tables that did
+  not have "create table" in its schema for SQLite column renaming.
+* Jifty::Module::Pluggable - Silence the @ISA warnings. 
+* Doc updates for Jifty::ClassLoader -- David Good <dgood at willingminds.com>
+* Created a method that can be over-ridden for custom test database setup
+* debian stuff, fr.po update
+
+Jifty 0.70416
+ * New ExtJS plugin (For yahoo-ui ext)
+ * zh-tw L10N for authen/passwd/user plugins.
+ * WWW::Mechanize 1.22 removed the form method.  
+   thanks to hdp for noticing/poking
+ * render_region should have default empty path.
+ * Jifty::Plugin::REST::Dispatcher - Gugod pointed out that we don't need to
+   stringify() the object-to-data output, because (esp for nested structures)
+   it's far more convenient to have the $accept-specific formatter (e.g.
+   YAML or JSON) to render it.
+ * Added render_as_yui_menubar in Menu.pm
+ * Upgraded YUI to 2.2.1
+ * NOTICE: if you are using yui tabview, 
+   please use tabview.css instead of tabs.css
+ * Added yui/element-beta.js and yui/menu.js in Web.pm
+ * Allow '->superuser' to be both an object and class method.
+ * added audreyt's Doxory demo app from doc/talks/yapcasia2007-doxory.pdf
+ *  Add doc and prefork dependency so the doc and dep tests pass
+ * Preforking server support for Jifty::Server
+ * Refactoring to support more template engines 
+ * fix "open" class in menu - active menu item doesn't imply current open item
+ * Jifty::Plugin - Authentication::Password now auto-loads LetMe and User.
+ * added a "SkipAccessControl" framework directive
+ * Doc: Add section on using models/actions outside of a Jifty app
+ * fix handling of multi-line data when encoded in JSON -- they should never 
+   wrap over multiple lines in generated output
+ * helpers improvements for T::D
+ * Make CurrentUser->new work as a method on an instance, so that 
+   as_superuser works.
+ * Added a 'None' session type for when your application doesn't need sessions
+ * Can't just check to see if the config exists to decide whether to 
+   initialze the Jifty object
+ * Make render_region resolve relative template in current context.
+ * We load the config on demand now, so it always exists. Test for 
+   classloader existence, instead of config existence, to tell whether or 
+   not we need to Jifty->new.
+ * Refactor the I18N plugin stuff to not fail tests.
+ * Make sure test coverage copes with new jifty->config 
+ * Better plugin I18N
+ * Plugin paths don't need to convert because File::ShareDir::module_dir
+   always returns an absolute path. I have added also modification checking
+   to the Jifty::I18N::refresh for plugin po files. -- Alexey Grebenschikov 
+ * Log::Log4perl::Appender::String (used in tests) was only added in 1.02; 
+   require at least that
+ * Switch Jifty->config to automatic instantiation
+ * Added a basic test stub for Jifty::Test::WWW::Mechanize. -sterling
+ * don't require a bunch of unused modules that don't trickle to the templates
+ * don't set the Home tab twice
+ * use Pod::Simple::HTML where we need it
+ * Administration and Online docs tabs are set in Jifty/Plugin/*/Dispatcher.pm
+ * When running coverage, don't use Class::Accessor::Named as it uses 
+   Hook::LexWrap
+ * don't load up PodSimple and other friends unless you've actually enabled 
+   AdminMode and brought OnlineDocs into the picture
+ * Modified submit_html_ok to make it behave like the documentation says it 
+   should.
+ * Don't create a new config object every time we look at the db version
+ * Added the ability to have a return button that looks like a submit button 
+   on a form.
+ * When you rest a lost password, email address is implicitly confirmed
+ * extracted dump_rules into DumpDispatcher plugin -dpavlin
+ * more quieting down of "couldn't drop that database that shouldn't have 
+   existed in the first place" warnings
+ * keep old LDAP and CAS plugins usable, 
+   THIS COULD BREAK APP MODELS NAME 
+   LDAPUser and CASUser models are now User -yves
+ * Autogenerate Package::Action when we need it
+ * Jifty: We now depend on Scalar::Defer 0.10 to not break the *_ 
+   localization.
+ * Jifty::DBI::Param::Schema - Mention how to use "defer".
+ * Remove legacy naming from the Auth::Password plugin #  nelhage++ 
+ * The plugin classloader is wrong. it's going away forever
+ * LetMes need to deal with user objects as superuser to get their tokens
+ * next major round of work on the login plugin. signup now works
+   slightly better debug logging from the jifty dispatcher
+ * Slightly better mail sending defaults
+ * When we use App::Class, actually require the module, to save the user some 
+   typing
+ * Changes to the dispatching to templates:
+ * only add '/index.html' to the path given if there is no template that can 
+   handle the given path.
+ * template_exists now checks for Template::Declare templates too
+ * tests that check that T::D templates are preferred over Mason templates.
+ * Set some svn:ignore properties so that generated files don't litter the 
+   tree
+ * Include the jifty skeleton app by default.
+ * make the 'hey! it's admin mode' bit not overwrite the menu
+ * TD fragments and unicode needed some massage.
+ * Next pass at a login/signup password auth plugin. Now supports login and 
+   logout and signup
+ * Jifty::CurrentUser now has a default "_init" behaviour.
+ * The password auth plugin now works
+ * Updated the 'feeds' section in J:M::Cookbook to not lie about the way 
+   XML::Feed actually works.  Arguably it /should/ work the way we described
+   ("your implementation is showing"), but fixing the docs was easier than 
+   submitting a patch to someone else's module.
+ * Now we can inherit actions from plugins
+ * fixed incorrect documentation of _ and added a SYNOPSIS
+ * "final" Mergedown of the Template-Declare branch of Jifty.
+  - New Template::Declare based templating system (optional)
+  - Significant work on plugins
+  - Significant refactoring
+  - Many jifty features extracted to 'mandatory' plugin applets. 
+    (These should be made optional or removable over time)
+ * Doc patch for how to do multiple "onclick" actions - jpollack at gmail.com
+ * Log::Log4perl::Appender::String (used in tests) was only added in
+    1.02; require at least that
+ * add doc to manage a superuser group
+ * add doc to emulate updated_on
+ * Add note to cookbook showing how to change other fields using ajax 
+   canonicalization
+ * Basic handler for running Jifty under mod_perl2.  Tested under Unbuntu
+   Feisty, with a default Apache2/MP2 install.  Requires a config change,
+   explained in the perldoc. -rodi
+ * examples/{Chat,Clock,Ping}/: Use Jifty::Server::Fork instead of
+   stub ::Server subclasses.
+ * Jifty::Server::Fork - New module to conveniently express
+   a forking builtin server.
+ * Plugin templates should override the core, but not application templates
+ * Since we use the schema tool to manage jifty's database, it's important 
+   that it be able to be called from running code (including a DESTROY block).   As it was, we were initializing (reinitializing) Jifty from within the 
+   DESTROY. That doesn't work so well.
+ * Better test for "jifty already initted"
+ * Fix adding columns during an upgrade.
+ * added a Deploying page to the manual based on the process I have found 
+   successful
+ * updated the upgrading manual and added a few extra glossary items
+ * DBD::pg passes postgres' warnings up, so try to convert their various
+   logging levels back to Log4Perl levels.
+   Completely heuristic, probably wants more guarding so it doesn't
+   reach out and bite someone.
+ * This quiets some of the most annoting warns revealed when I removed
+   the log-level downing in Script/Schema.pm
+ * Added support for schema_version() in records
+ * Updated the schema upgrade process to handle renames more nicely
+ * Added a simple test for upgrading
+ * YAML.pm is currently required even if YAML::Syck is present.
+   The Makefile now requires YAML even if you have a C compiler 
+   and are installing YAML::Syck.
+ * added a CUSTOMIZATION section to the Jifty::Action docs
+ * upping require for IPC::PubSub to 0.23 due to use of disconnect
+ * Disconnect PubSub before dropping the database
+ * Solve copious global destruction warnings
+ * send correct HTTP/1.1 headers for caching when running Jifty with 
+   DevelMode: 0
+ * Support POSTing to /=/model/Foo to create items without specifying a PK
+ * lib/Jifty/Manual/TutorialRest.pod - quick overview of REST plugin
+ * don't double warn.  Now that we stopped schema creation from suppressing 
+   warnings this *shouldn't* be necesary
+ * stop hiding messages/warns from the database during tests
+ * default to only showing WARN and higher when running tests 
+   (rather than our more normal INFO)
+ * Added the ability to force arguments and path when rengering a region. 
+   This lets developers force override something passed in via ajax or a 
+   "sticky" value from a previous request.
+ * Jifty::Script - Assume "jifty fastcgi" when we are running under cgi.
+ * I18N and zh-* L10N for menu and halo.
+ * fix JScript conditional compilation bug. Jifty.Utils.isMSIE works now.
+ * strict, warnings, and redefinition warning avoidance for 
+   J::Module::Pluggable.
+ * Alternate implementation of Module::Pluggable::Object's _require method to 
+   avoid a useless string eval.
+ * Actually carp from within our log warning handler, to not swallow critical 
+   debugging into
+ * Jifty::Logger - Properly respect previous $SIG{__WARN__} handler
+   if Log4Perl isn't yet initialized; that means we won't silently
+   discard compile-time errors from our model classes, though they
+   are still demoted as warnings.
+ * Refactored Jifty::Script::Schema to use extracted column, table and db 
+   manipulation routines
+ * Extract the "load model related classes" logic in the class loader to its 
+   own function
+ * A new method provides a tantalizing glimpse of jifty's forthcoming "load 
+   models from the database" support
+ * Added table and column schema generation methods to Jifty::Record, based on   an extraction of Jifty::Script::Schema
+ * Added "create db" and "drop db" methods to Jifty::Handle
+ * Added the 'bootstrap' option to vanilla Jifty::CurrentUser. Now there's one   fewer cases where you need a custom CurrentUser class
+ * Jifty::Util - Add a generate_uuid method and use it to generate 
+   ApplicationUUID.
+ * Jifty::Script::App - Make the generated Makefile.PL more canonical.
+ * Jifty::Util - only requires ExtUtils::MM at request.
+ * Jifty::Util - fixed the broken Win32 logic:
+  - use ExtUtils::MM before calling MM->maybe_command
+  - ignore the case of letters when comparing file names
+ * Change all tests for the literal Driver string "SQLite"
+   to a regex match to /SQLite/, in anticipation of fancy
+   drivers such as SVK::SQLite.
+ * enable UTF-8 flag awarness in JSON libraries to fix problem in validation
+   of values during creating a record via the admin interface when column has
+   valid values with unicode chars.
+ * include iepngfix 1.0
+ * add MIME type text/x-component for .htc file
+ * howto document for iepngfix
+ * Our fallback I18N handle needs to specify that it should autocreate keys 
+   if they're not found
+ * Jifty::I18N: Provide a default fallback lexicon class for "en"
+   so Locale::Maketext won't clobber our $@ stack.
+ * Jifty::I18N - Avoid naked eval{} that clobbers $@.
+ * Jifty::Web - Add private accessor for _state_variables to
+   avoid typo-prone ->{'state_variables'}.
+ * REST: Implementation for PUT and DELETE on model items
+ * Canonicalize/validate after typing and blurring, too
+ * Modernization of model declarations for compatibility with new 
+   Object::Declare based Jifty::DBI
+ * updating to  'max_length' name for the parameter formerly known as 'length'
+ * Jifty: Deprecate ->length in web form and param fields;
+    write ->max_length instead.
+ * Allow create, load_or_create and load_by_cols to be used as class methods.
+ * REST: Show an action HTML form when rendering /=/action/App.Action.Foo as 
+   HTML
+ * Fix running actions (checking for allowed-ness was done wrong)
+ * Cut down on a lot of the crap that we outputed and fix up structure
+ * Make it possible to request XML from the URL like the other data formats
+ * Show action params in any data format instead of just an HTML form
+ * Only allow method calls if the "field" is actually a column
+ * Force stringification so that we don't segfault trying to output blessed 
+   references and what not
+ * added the update method which reconstructs the locale
+   handle (used by Jifty::Handler::handle_request) [Jifty::I18N]
+ * &_(loc) now uses the global locale handle instead of
+   the one set up during Jifty::I18N->new().  [Jifty::I18N]
+ * Audrey's refresh method now always calls C<update>
+  either directly or indirectly (via C<new>) [Jifty::I18N]
+ * C<handle_request> now always calls
+  Jifty::I18N->update directly or indirectly
+  (via C<Jifty::I18N->refresh>) [Jifty::Handler]
+ * Misc minor startup-time performance improvements
+ * Only run onsubmit() if we have an onsubmit property
+ * Support for controlling browser-based autocomplete on form fields
+ * Fix how fake buttons submit forms -trs
+ * Gotta double-quote keybinding labels if they have embedded newlines.
+ * Warnings when a developer puts a "show" into a "before" or "after" 
+   dispatcher rule.
+ 
+
+
 Jifty 0.70117
    Dependencies: 
      * Bumped the minimum required version of Jifty::DBI to 0.30

Modified: jifty/branches/virtual-models/MANIFEST
==============================================================================
--- jifty/branches/virtual-models/MANIFEST	(original)
+++ jifty/branches/virtual-models/MANIFEST	Mon May  7 16:28:32 2007
@@ -27,6 +27,7 @@
 doc/jifty-model-svk
 doc/jifty-plugins-2.0
 doc/jifty-web-form-etc
+doc/notes-on-distributed-operations
 doc/packaging
 doc/plugin-requirements
 doc/plugin-syntax
@@ -54,6 +55,29 @@
 examples/Clock/Makefile.PL
 examples/Clock/share/web/templates/fragments/time
 examples/Clock/share/web/templates/index.html
+examples/Doxory/bin/jifty
+examples/Doxory/doxory
+examples/Doxory/etc/config.yml
+examples/Doxory/lib/Doxory/Dispatcher.pm
+examples/Doxory/lib/Doxory/Model/Choice.pm
+examples/Doxory/lib/Doxory/Model/User.pm
+examples/Doxory/lib/Doxory/Model/Vote.pm
+examples/Doxory/lib/Doxory/View.pm
+examples/Doxory/Makefile.PL
+examples/Doxory/share/po/zh_cn.po
+examples/Doxory/share/po/zh_tw.po
+examples/Doxory/t/00-model-User.t
+examples/Example-Todo/bin/jifty
+examples/Example-Todo/etc/config.yml
+examples/Example-Todo/example_todo
+examples/Example-Todo/inc/Module/Install.pm
+examples/Example-Todo/inc/Module/Install/Base.pm
+examples/Example-Todo/inc/Module/Install/Metadata.pm
+examples/Example-Todo/inc/Module/Install/WriteAll.pm
+examples/Example-Todo/lib/Example/Todo/Model/Todo.pm
+examples/Example-Todo/Makefile.PL
+examples/Example-Todo/META.yml
+examples/Example-Todo/t/00-model-Todo.t
 examples/HelloKitty/bin/jifty
 examples/HelloKitty/etc/config.yml
 examples/HelloKitty/hellokitty
@@ -151,25 +175,38 @@
 lib/Jifty/Param/Schema.pm
 lib/Jifty/Plugin.pm
 lib/Jifty/Plugin/AdminUI.pm
-lib/Jifty/Plugin/AdminUI/View-not-yet.pm
 lib/Jifty/Plugin/Authentication/Password.pm
+lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm
 lib/Jifty/Plugin/Authentication/Password/Action/GeneratePasswordToken.pm
 lib/Jifty/Plugin/Authentication/Password/Action/Login.pm
-lib/Jifty/Plugin/Authentication/Password/Model/User.pm
+lib/Jifty/Plugin/Authentication/Password/Action/Logout.pm
+lib/Jifty/Plugin/Authentication/Password/Action/ResendConfirmation.pm
+lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm
+lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm
+lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm
+lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm
+lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm
+lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm
+lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm
+lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm
+lib/Jifty/Plugin/Authentication/Password/View.pm
 lib/Jifty/Plugin/ClassLoader.pm
 lib/Jifty/Plugin/CompressedCSSandJS.pm
 lib/Jifty/Plugin/CompressedCSSandJS/Dispatcher.pm
 lib/Jifty/Plugin/ErrorTemplates.pm
 lib/Jifty/Plugin/ErrorTemplates/View.pm
 lib/Jifty/Plugin/Halo.pm
+lib/Jifty/Plugin/LetMe.pm
+lib/Jifty/Plugin/LetMe/Dispatcher.pm
 lib/Jifty/Plugin/OnlineDocs.pm
+lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm
 lib/Jifty/Plugin/REST.pm
 lib/Jifty/Plugin/REST/Dispatcher.pm
 lib/Jifty/Plugin/SkeletonApp.pm
 lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm
 lib/Jifty/Plugin/SkeletonApp/View.pm
 lib/Jifty/Plugin/User.pm
-lib/Jifty/Plugin/User/Model/User.pm
+lib/Jifty/Plugin/User/Mixin/Model/User.pm
 lib/Jifty/Plugin/Yullio/View.pm
 lib/Jifty/Record.pm
 lib/Jifty/Request.pm
@@ -193,6 +230,8 @@
 lib/Jifty/Script/Server.pm
 lib/Jifty/Server.pm
 lib/Jifty/Server/Fork.pm
+lib/Jifty/Server/Prefork.pm
+lib/Jifty/Server/Prefork/NetServer.pm
 lib/Jifty/Subs.pm
 lib/Jifty/Subs/Render.pm
 lib/Jifty/Test.pm
@@ -232,6 +271,7 @@
 lib/Jifty/Web/PageRegion.pm
 lib/Jifty/Web/Session.pm
 lib/Jifty/Web/Session/ClientSide.pm
+lib/Jifty/Web/Session/None.pm
 lib/Jifty/YAML.pm
 Makefile.PL
 MANIFEST			This list of files
@@ -263,7 +303,7 @@
 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Action/CASLogout.pm
 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/CurrentUser.pm
 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Dispatcher.pm
-plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Model/CASUser.pm
+plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Model/User.pm
 plugins/AuthCASOnly/Makefile.PL
 plugins/AuthCASOnly/MANIFEST
 plugins/AuthCASOnly/share/web/templates/caslogin
@@ -295,7 +335,7 @@
 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Action/LDAPLogout.pm
 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/CurrentUser.pm
 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Dispatcher.pm
-plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Model/LDAPUser.pm
+plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Model/User.pm
 plugins/AuthLDAPOnly/Makefile.PL
 plugins/AuthLDAPOnly/MANIFEST
 plugins/AuthLDAPOnly/share/po/en.po
@@ -312,6 +352,8 @@
 plugins/AuthzLDAP/share/po/fr.po
 plugins/AuthzLDAP/share/web/templates/error/AccessDenied
 plugins/AuthzLDAP/t/00-load.t
+plugins/DumpDispatcher/lib/Jifty/Plugin/DumpDispatcher.pm
+plugins/DumpDispatcher/Makefile.PL
 plugins/EditInPlace/debian/changelog
 plugins/EditInPlace/debian/compat
 plugins/EditInPlace/debian/control
@@ -342,6 +384,332 @@
 plugins/EmailErrors/lib/Jifty/Plugin/EmailErrors/Notification/EmailError.pm
 plugins/EmailErrors/Makefile.PL
 plugins/EmailErrors/share/web/templates/.file
+plugins/ExtJS/lib/Jifty/Plugin/ExtJS.pm
+plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Dispatcher.pm
+plugins/ExtJS/Makefile.PL
+plugins/ExtJS/share/web/static/css/extjs/basic-dialog.css
+plugins/ExtJS/share/web/static/css/extjs/box.css
+plugins/ExtJS/share/web/static/css/extjs/button.css
+plugins/ExtJS/share/web/static/css/extjs/combo.css
+plugins/ExtJS/share/web/static/css/extjs/core.css
+plugins/ExtJS/share/web/static/css/extjs/date-picker.css
+plugins/ExtJS/share/web/static/css/extjs/dd.css
+plugins/ExtJS/share/web/static/css/extjs/debug.css
+plugins/ExtJS/share/web/static/css/extjs/ext-all.css
+plugins/ExtJS/share/web/static/css/extjs/form.css
+plugins/ExtJS/share/web/static/css/extjs/grid.css
+plugins/ExtJS/share/web/static/css/extjs/layout.css
+plugins/ExtJS/share/web/static/css/extjs/menu.css
+plugins/ExtJS/share/web/static/css/extjs/qtips.css
+plugins/ExtJS/share/web/static/css/extjs/README.txt
+plugins/ExtJS/share/web/static/css/extjs/reset-min.css
+plugins/ExtJS/share/web/static/css/extjs/resizable.css
+plugins/ExtJS/share/web/static/css/extjs/tabs.css
+plugins/ExtJS/share/web/static/css/extjs/toolbar.css
+plugins/ExtJS/share/web/static/css/extjs/tree.css
+plugins/ExtJS/share/web/static/css/extjs/ytheme-aero.css
+plugins/ExtJS/share/web/static/css/extjs/ytheme-gray.css
+plugins/ExtJS/share/web/static/css/extjs/ytheme-vista.css
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close-over.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-center.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-left.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-right.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/close.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse-over.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand-over.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/hd-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/w-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-blue-split.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-hrow.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-split.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-vista-hd.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/pspbrwse.jbf
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort-col-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_asc.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_desc.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-expand.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-close.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-light-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close-on.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/qtip/bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/s.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.png
+plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-btm-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/bg.gif
+plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/tb-btn-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-arrow.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/close.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/hd-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress2.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/corners-blue.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/corners.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/l-blue.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/l.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/r-blue.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/r.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/tb-blue.gif
+plugins/ExtJS/share/web/static/images/extjs/default/box/tb.gif
+plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-add.gif
+plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-no.gif
+plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-yes.gif
+plugins/ExtJS/share/web/static/images/extjs/default/form/date-trigger.gif
+plugins/ExtJS/share/web/static/images/extjs/default/form/error-tip-corners.gif
+plugins/ExtJS/share/web/static/images/extjs/default/form/exclamation.gif
+plugins/ExtJS/share/web/static/images/extjs/default/form/text-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/form/trigger.gif
+plugins/ExtJS/share/web/static/images/extjs/default/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-left-white.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-right-white.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-bottom.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-top.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/dirty.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/done.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-no.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-yes.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/footer-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-hd.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-split.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-hrow.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-loading.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-split.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-vista-hd.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-asc.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-desc.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.png
+plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.png
+plugins/ExtJS/share/web/static/images/extjs/default/grid/invalid_line.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/loading.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/mso-hd.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/nowait.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first-disabled.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last-disabled.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next-disabled.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev-disabled.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/pick-button.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/refresh.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_asc.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_desc.gif
+plugins/ExtJS/share/web/static/images/extjs/default/grid/Thumbs.db
+plugins/ExtJS/share/web/static/images/extjs/default/grid/wait.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-expand.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-close.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-light-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/stick.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/stuck.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close-on.gif
+plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close.gif
+plugins/ExtJS/share/web/static/images/extjs/default/menu/checked.gif
+plugins/ExtJS/share/web/static/images/extjs/default/menu/group-checked.gif
+plugins/ExtJS/share/web/static/images/extjs/default/menu/menu-parent.gif
+plugins/ExtJS/share/web/static/images/extjs/default/menu/menu.gif
+plugins/ExtJS/share/web/static/images/extjs/default/menu/unchecked.gif
+plugins/ExtJS/share/web/static/images/extjs/default/qtip/bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/qtip/close.gif
+plugins/ExtJS/share/web/static/images/extjs/default/qtip/tip-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/default/s.gif
+plugins/ExtJS/share/web/static/images/extjs/default/shadow-lr.png
+plugins/ExtJS/share/web/static/images/extjs/default/shadow.png
+plugins/ExtJS/share/web/static/images/extjs/default/shared/calendar.gif
+plugins/ExtJS/share/web/static/images/extjs/default/shared/left-btn.gif
+plugins/ExtJS/share/web/static/images/extjs/default/shared/right-btn.gif
+plugins/ExtJS/share/web/static/images/extjs/default/shared/warning.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/square.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow-light.gif
+plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow.gif
+plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-over-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/toolbar/gray-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-btn-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-add.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-between.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-no.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-over.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-under.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-yes.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus-nl.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus-nl.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-line.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus-nl.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus-nl.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/folder-open.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/folder.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/leaf.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/loading.gif
+plugins/ExtJS/share/web/static/images/extjs/default/tree/s.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/close.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/dlg-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/hd-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/grid/grid-hrow.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-expand.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-close.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-light-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/stick.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close-on.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/menu/checked.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/menu/group-checked.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu-parent.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/menu/unchecked.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/qtip/bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/qtip/tip-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/s.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/gray-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/tb-btn-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-center.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-left.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-right.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/close.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/dlg-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/hd-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/w-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-split.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-vista-hd.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/expand.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/gradient-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-collapse.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-expand.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-close.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-light-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/stick.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close-on.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/qtip/bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/qtip/tip-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/s.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle-dark.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-left-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-right-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-sprite.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/gray-bg.gif
+plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/tb-btn-sprite.gif
+plugins/ExtJS/share/web/static/js/extjs/adapter/jquery/ext-jquery-adapter.js
+plugins/ExtJS/share/web/static/js/extjs/adapter/prototype/ext-prototype-adapter.js
+plugins/ExtJS/share/web/static/js/extjs/adapter/yui/ext-yui-adapter.js
+plugins/ExtJS/share/web/static/js/extjs/adapter/yui/yui-utilities.js
+plugins/ExtJS/share/web/static/js/extjs/ext-all.js
+plugins/ExtJS/share/web/static/js/extjs/ext-config.js
 plugins/LetMe/lib/Jifty/Plugin/LetMe.pm
 plugins/LetMe/lib/Jifty/Plugin/LetMe/Dispatcher.pm
 plugins/LetMe/Makefile.PL
@@ -432,8 +800,22 @@
 share/web/static/css/nav.css
 share/web/static/css/notices.css
 share/web/static/css/yui/calendar/calendar.css
+share/web/static/css/yui/menu/map.gif
+share/web/static/css/yui/menu/menu.css
+share/web/static/css/yui/menu/menuarodwn8_dim_1.gif
+share/web/static/css/yui/menu/menuarodwn8_hov_1.gif
+share/web/static/css/yui/menu/menuarodwn8_nrm_1.gif
+share/web/static/css/yui/menu/menuarorght8_dim_1.gif
+share/web/static/css/yui/menu/menuarorght8_hov_1.gif
+share/web/static/css/yui/menu/menuarorght8_nrm_1.gif
+share/web/static/css/yui/menu/menuaroup8_dim_1.gif
+share/web/static/css/yui/menu/menuaroup8_nrm_1.gif
+share/web/static/css/yui/menu/menuchk8_dim_1.gif
+share/web/static/css/yui/menu/menuchk8_hov_1.gif
+share/web/static/css/yui/menu/menuchk8_nrm_1.gif
 share/web/static/css/yui/tabview/border_tabs.css
 share/web/static/css/yui/tabview/tabs.css
+share/web/static/css/yui/tabview/tabview.css
 share/web/static/favicon.ico
 share/web/static/images/css/bullet_arrow_down.png
 share/web/static/images/css/bullet_arrow_up.png
@@ -495,7 +877,9 @@
 share/web/static/js/yui/calendar.js
 share/web/static/js/yui/container.js
 share/web/static/js/yui/dom.js
+share/web/static/js/yui/element-beta.js
 share/web/static/js/yui/event.js
+share/web/static/js/yui/menu.js
 share/web/static/js/yui/tabview.js
 share/web/static/js/yui/yahoo.js
 share/web/templates/=/subs
@@ -527,6 +911,7 @@
 SIGNATURE
 t/00-load.t
 t/01-dependencies.t
+t/01-test-mechanize.t
 t/01-test-web.t
 t/01-version_checks.t
 t/02-connect.t
@@ -577,9 +962,15 @@
 t/TestApp-Plugin-PasswordAuth/etc/config.yml
 t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/FasterSwallow.pm
 t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/FavoriteColor.pm
+t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Bootstrap.pm
+t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/CurrentUser.pm
+t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Dispatcher.pm
 t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model/User.pm
 t/TestApp-Plugin-PasswordAuth/Makefile.PL
 t/TestApp-Plugin-PasswordAuth/t/00-model-User.t
+t/TestApp-Plugin-PasswordAuth/t/01-tokengen.t
+t/TestApp-Plugin-PasswordAuth/t/11-current_user.t
+t/TestApp-Plugin-PasswordAuth/t/12-signup.t
 t/TestApp-Plugin-REST/bin/jifty
 t/TestApp-Plugin-REST/etc/config.yml
 t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Action/DoSomething.pm
@@ -598,6 +989,8 @@
 t/TestApp/lib/TestApp/Model/User.pm
 t/TestApp/lib/TestApp/Upgrade.pm
 t/TestApp/lib/TestApp/View.pm
+t/TestApp/lib/TestApp/View/base.pm
+t/TestApp/lib/TestApp/View/instance.pm
 t/TestApp/share/web/static/images/pony.jpg
 t/TestApp/share/web/templates/concrete.html
 t/TestApp/share/web/templates/currentuser
@@ -607,6 +1000,10 @@
 t/TestApp/share/web/templates/editform
 t/TestApp/share/web/templates/index.html
 t/TestApp/share/web/templates/manual_redirect
+t/TestApp/share/web/templates/path_test/foo/index.html
+t/TestApp/share/web/templates/path_test/in_both
+t/TestApp/share/web/templates/path_test/mason_only
+t/TestApp/share/web/templates/redirected
 t/TestApp/share/web/templates/regions/list
 t/TestApp/share/web/templates/regions/long
 t/TestApp/share/web/templates/regions/short
@@ -629,9 +1026,12 @@
 t/TestApp/t/11-current_user.t
 t/TestApp/t/12-search.t
 t/TestApp/t/13-page-regions.t
+t/TestApp/t/14-template-paths.t
+t/TestApp/t/15-template-subclass.t
 t/TestApp/t/config-Cachable
 t/TestApp/t/config-Record
 t/TestApp/t/i18n-standalone.t
 t/TestApp/t/instance_id.t
 t/TestApp/t/regex_meta_in_path_info.t
 t/TestApp/t/upgrade.t
+t/TestApp/testapp

Modified: jifty/branches/virtual-models/META.yml
==============================================================================
--- jifty/branches/virtual-models/META.yml	(original)
+++ jifty/branches/virtual-models/META.yml	Mon May  7 16:28:32 2007
@@ -1,19 +1,22 @@
+--- 
 build_requires: 
   ExtUtils::MakeMaker: 6.11
 distribution_type: module
-generated_by: Module::Install version 0.640
+generated_by: Module::Install version 0.650
 license: Perl
+meta-spec: 
+  url: http://module-build.sourceforge.net/META-spec-v1.3.html
+  version: 1.3
 name: Jifty
 no_index: 
   directory: 
-    - share
-    - t
+    - debian
     - doc
+    - examples
     - inc
     - t
   package: 
     - DB
-    - inc
 recommends: 
   Apache2::Const: 0
   Class::Accessor::Named: 0
@@ -23,16 +26,13 @@
   Module::Install::Admin: 0.50
   Module::Refresh: 0.09
   Net::Server::Fork: 0
+  Net::Server::PreFork: 0
   PAR::Dist::FromCPAN: 0
   Test::Base: 0.44
   Test::HTML::Lint: 0
   Test::HTTP::Server::Simple: 0.02
   Test::MockModule: 0.05
   Test::MockObject: 1.07
-  Test::More: 0.62
-  Test::Pod::Coverage: 0
-  Test::WWW::Mechanize: 1.04
-  WWW::Mechanize: 1.12
 requires: 
   App::CLI: 0.03
   CGI: 3.19
@@ -75,7 +75,7 @@
   Hook::LexWrap: 0
   IPC::PubSub: 0.23
   JSON::Syck: 0.15
-  Jifty::DBI: 0.31
+  Jifty::DBI: 0.40
   LWP::UserAgent: 0
   Locale::Maketext::Extract: 0.20
   Locale::Maketext::Lexicon: 0.60
@@ -90,13 +90,17 @@
   Params::Validate: 0
   Pod::Simple: 0
   SQL::ReservedWords: 0
-  Scalar::Defer: 0.06
+  Scalar::Defer: 0.10
   Shell::Command: 0
   String::Koremutake: 0
-  Template::Declare: 0.06
+  Template::Declare: 0.07
   Test::Base: 0
+  Test::More: 0.62
+  Test::Pod::Coverage: 0
+  Test::WWW::Mechanize: 1.04
   UNIVERSAL::require: 0
   URI: 0
+  WWW::Mechanize: 1.12
   XML::Simple: 0
   XML::Writer: 0.601
   XML::XPath: 0
@@ -105,4 +109,4 @@
   perl: 5.8.3
   version: 0
 tests: t/*.t t/*/t/*.t
-version: 0.70117
+version: 0.70415

Modified: jifty/branches/virtual-models/Makefile.PL
==============================================================================
--- jifty/branches/virtual-models/Makefile.PL	(original)
+++ jifty/branches/virtual-models/Makefile.PL	Mon May  7 16:28:32 2007
@@ -42,7 +42,7 @@
 requires('Hash::Merge');
 requires('Hook::LexWrap');
 requires('IPC::PubSub' => '0.23' );
-requires('Jifty::DBI' => '0.31' );            # Jifty::DBI::Collection Jifty::DBI::Handle Jifty::DBI::Record::Cachable Jifty::DBI::SchemaGenerator
+requires('Jifty::DBI' => '0.40' );            # Jifty::DBI::Collection Jifty::DBI::Handle Jifty::DBI::Record::Cachable Jifty::DBI::SchemaGenerator
 requires('Locale::Maketext::Extract' => '0.20');
 requires('Locale::Maketext::Lexicon' => '0.60');
 requires('Log::Log4perl' => '1.04');
@@ -62,9 +62,12 @@
 requires('SVN::Fs');
 requires('SVN::Repos');
 requires('SVN::Simple::Edit');
-requires('Template::Declare');                # Template::Declare::Tags
-requires('Template::Declare' => '0.06');                # Template::Declare::Tags
+requires('Template::Declare' => '0.07');                # Template::Declare::Tags
 requires('Test::Base');
+requires('Test::More' => 0.62 ),
+requires('Test::Pod::Coverage'),
+requires('Test::WWW::Mechanize' => 1.04 ),
+requires('WWW::Mechanize' => 1.12 ),
 requires('UNIVERSAL::require');
 requires('URI');
 requires('XML::Writer' => '0.601');
@@ -97,12 +100,8 @@
         recommends('Module::Install::Admin' => '0.50'),
         ($^O ne 'MSWin32' ? recommends('Test::HTTP::Server::Simple' => '0.02' ) : ()),
         recommends('Test::HTML::Lint'),
-        recommends('Test::More' => 0.62 ),
         recommends('Test::MockModule' => '0.05'),
         recommends('Test::MockObject' => '1.07'),
-        recommends('Test::Pod::Coverage'),
-        recommends('Test::WWW::Mechanize' => 1.04 ),
-        recommends('WWW::Mechanize' => 1.12 ),
         recommends('Module::Refresh' => '0.09')
     ],
     'Development of the jifty framework' => [
@@ -117,6 +116,10 @@
         -default => 0,
         recommends('Net::Server::Fork'),
     ],
+    'Pre-forking jifty server' => [
+        -default => 0,
+        recommends('Net::Server::PreFork'),
+    ],
     'Apache2/ModPerl2 handler' => [
         -default => 0,
         recommends('Apache2::Const'),
@@ -128,11 +131,8 @@
 );
 
 
-no_index directory => 'share';
-no_index directory => 't';
+no_index( directory => qw< debian doc examples share plugins/*/t> );
 no_index package => 'DB';
-no_index package => 'inc';
-no_index directory => 'doc';
 
 version_from('lib/Jifty.pm');
 #&auto_bundle_deps();

Modified: jifty/branches/virtual-models/SIGNATURE
==============================================================================
--- jifty/branches/virtual-models/SIGNATURE	(original)
+++ jifty/branches/virtual-models/SIGNATURE	Mon May  7 16:28:32 2007
@@ -1,12 +1,12 @@
 This file contains message digests of all files listed in MANIFEST,
-signed via the Module::Signature module, version 0.41.
+signed via the Module::Signature module, version 0.55.
 
 To verify the content in this distribution, first make sure you have
 Module::Signature installed, then type:
 
     % cpansign -v
 
-It would check each file's integrity, as well as the signature's
+It will check each file's integrity, as well as the signature's
 validity.  If "==> Signature verified OK! <==" is not displayed,
 the distribution may already have been compromised, and you should
 not run its Makefile.PL or Build.PL.
@@ -14,12 +14,12 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-SHA1 ef933bd94b1e449d781c19e74a92412f08e602c5 AUTHORS
-SHA1 fc571a41cf0774f0099bd365a6e21607a2da0151 Changelog
-SHA1 8c31edaf5f07a1bae38d787bbdf2d79bb17d6f7c MANIFEST
+SHA1 7ce15e058bb6a72aa237ac58e0fbce934b2fef5c AUTHORS
+SHA1 876166ca6f2cf7bfa6a6137070beb1b55b4bc4ce Changelog
+SHA1 ed26a91a1edcc0aed0509bc7384b2d24cfd13d89 MANIFEST
 SHA1 d4adbf5948041cd460da5cb7ad21394a790e2022 MANIFEST.SKIP
-SHA1 f7177c83690e1bac7930f31b96c991afb6adbc8b META.yml
-SHA1 767b1c8e6573516120842aabb2033fddab178d39 Makefile.PL
+SHA1 85f15b04e047acd8c86edfca3f7760fa4c001584 META.yml
+SHA1 c11c8ba944d2d9410d04593112e7ab951648d4fd Makefile.PL
 SHA1 e395a2eabaf8faf8266dedc664c1eb52c6c589cf README
 SHA1 aaf8f7a1025fc97077072672f325e2a5f3c03a41 bin/build_par
 SHA1 f7f44f9a7337def0c97f981073e3ed970851d9ae bin/jifty
@@ -27,9 +27,9 @@
 SHA1 9a91a81e3db1a12368153fed9e504aad492cd971 bin/service
 SHA1 543a2677f66d3c8ca671b790509b6c1721ac6270 bin/xgettext
 SHA1 1c042485ba8a21f0f124dd8ed412d43d3805430e debian/README
-SHA1 43b4786695f70ebd8ee74aac9e7eb270b4641b63 debian/changelog
+SHA1 dee0467ffdb9142223c49789a447ba5dd299c28d debian/changelog
 SHA1 5d9474c0309b7ca09a182d888f73b37a8fe1362c debian/compat
-SHA1 73f845d1185d0d977dd5bea3f046a0ae53451363 debian/control
+SHA1 c9a13c7f88cc191d5167bbdeebf5e7abbd776b0b debian/control
 SHA1 8fc130ffa6d53c47d94eab1616887c511d54d61f debian/rules
 SHA1 b8bb315ef8fbdd2f069b6339ad0461b5d933d7da doc/ajax-upgraded-links
 SHA1 a0d03921821ca39ea461f1f9fa812fdbb5f501a0 doc/building_a_par
@@ -45,8 +45,10 @@
 SHA1 0eab037e835b3d998df54883377b58802cb78f7a doc/jifty-action-record-search
 SHA1 4f01bbe985a1ad3742b48563992bdbf032a6ce4d doc/jifty-dispatcher.graffle
 SHA1 b07f1666f9da714a9007058ea74d0d4cfa31ebfe doc/jifty-dispatcher.svg
+SHA1 b62f3916546fc54639e277434646b8d4f253d6d7 doc/jifty-model-svk
 SHA1 29514abbc940365a861d196d8b1f35ee34f91526 doc/jifty-plugins-2.0
 SHA1 94a787c12228136c7797f81fef39e9bb52786067 doc/jifty-web-form-etc
+SHA1 fc7ea00184c4632731c3131f225fded7eeedfa0f doc/notes-on-distributed-operations
 SHA1 44839f806443cbb6469f3610f9a6c488d1777f60 doc/packaging
 SHA1 3ec038720e82a1297a3a5db6a0e1b24fe0aa13c2 doc/plugin-requirements
 SHA1 3de2d7f062e78fc8b543f6b93e79852274c6c657 doc/plugin-syntax
@@ -59,10 +61,9 @@
 SHA1 9db8566a4bacf0f3be943b9b3a84c45439c45337 etc/site_config.yml
 SHA1 3d3cce325969be4618e89c976aa9f950618ff39a examples/Chat/Makefile.PL
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 examples/Chat/bin/jifty
-SHA1 418a81711645390f06a417a0e4328901c9c92dc4 examples/Chat/etc/config.yml
+SHA1 c163b8cb161f5e9db259b4045249416f70ea4e01 examples/Chat/etc/config.yml
 SHA1 08043c294b69d1a2e23940346034283e6f686e14 examples/Chat/lib/Chat/Action/Send.pm
 SHA1 63f552215f7ed2d75278509fab4324dddda90591 examples/Chat/lib/Chat/Event/Message.pm
-SHA1 a8c6b5a40ec985c240db0cfc56922d534b9dd60d examples/Chat/lib/Chat/Server.pm
 SHA1 f6f5a7db0d950b19cb3a0e2f0776ac4fc0186082 examples/Chat/share/web/templates/fragments/message
 SHA1 ceb9ecbd5ba19436ff3cfe423e688bcc0d4b1adc examples/Chat/share/web/templates/fragments/sender
 SHA1 047c066b5f143e1a80056fa158e172448ee912e5 examples/Chat/share/web/templates/index.html
@@ -71,11 +72,38 @@
 SHA1 3d3cce325969be4618e89c976aa9f950618ff39a examples/Clock/Makefile.PL
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 examples/Clock/bin/jifty
 SHA1 faca2e649d4d9b4b00f5f6bf8932a7610c698415 examples/Clock/clockserv.pl
-SHA1 793ef4d540d2df071daad4ad73514c75d8e9aa51 examples/Clock/etc/config.yml
+SHA1 fc48886cd6416e638542c6827570643eb7cdff9e examples/Clock/etc/config.yml
 SHA1 72feb5e40abfac4e87793b427f9de45c03cfaca4 examples/Clock/lib/Clock/Event/Tick.pm
-SHA1 c2e597a83448804e04989db290404766180033ab examples/Clock/lib/Clock/Server.pm
 SHA1 e70cea658fbef26cdeb5558b89dd9c6890fbd9db examples/Clock/share/web/templates/fragments/time
 SHA1 bddc300d6e81f578c85a8807156822d682c61efe examples/Clock/share/web/templates/index.html
+SHA1 8fe8876037756db9f78ab1d6668bfcc23617414d examples/Doxory/Makefile.PL
+SHA1 f7f44f9a7337def0c97f981073e3ed970851d9ae examples/Doxory/bin/jifty
+SHA1 8a919440feae546381249bc49d9404559b7cf616 examples/Doxory/doxory
+SHA1 7996887eb81370c19d58a348632797c1c1d976f5 examples/Doxory/etc/config.yml
+SHA1 148918761e3d8e6a993f3d0f64e66f384dc8e5ea examples/Doxory/lib/Doxory/Dispatcher.pm
+SHA1 f0a1cfd87b47f0d040768abd07b885735ced7781 examples/Doxory/lib/Doxory/Model/Choice.pm
+SHA1 63105b35272344140c78a4d49c99fb6329fdfee0 examples/Doxory/lib/Doxory/Model/User.pm
+SHA1 4dcb58ff5b7e88c3e503a0b21923ead70936677c examples/Doxory/lib/Doxory/Model/Vote.pm
+SHA1 bf67169daeeadc6a18d6b948830d440a89c00176 examples/Doxory/lib/Doxory/View.pm
+SHA1 149b55cfb72c0def0ab7b495445baf8c631ce621 examples/Doxory/share/po/zh_cn.po
+SHA1 bec6af6333016377d442c59bdaaf32ab65a31e4a examples/Doxory/share/po/zh_tw.po
+SHA1 561110ddd8574426cb578a3c81d356bdc4fa47f3 examples/Doxory/t/00-model-User.t
+SHA1 da39a3ee5e6b4b0d3255bfef95601890afd80709 examples/Example-Todo/META.yml
+SHA1 aef127e349b9e06adaad2bec98622582c175e795 examples/Example-Todo/Makefile.PL
+SHA1 f7f44f9a7337def0c97f981073e3ed970851d9ae examples/Example-Todo/bin/jifty
+SHA1 3edcfa5651b780a6e31e4c0e6ad28f3bf22c45ea examples/Example-Todo/etc/config.yml
+SHA1 751fdf0397a92d3bc7f034b3fd08b3438b0eb27f examples/Example-Todo/example_todo
+SHA1 9b2f9d83bcf77860f53a0c07c90a4a59ad9f5df1 examples/Example-Todo/inc/Module/Install.pm
+SHA1 abe32855d75ab13747cf65765af9947b7a8c3057 examples/Example-Todo/inc/Module/Install/Base.pm
+SHA1 381bb98ea3877bba49ae85e7a7ea130645fd3dbf examples/Example-Todo/inc/Module/Install/Metadata.pm
+SHA1 e827d6d43771032fa3df35c0ad5e5698d0e54cda examples/Example-Todo/inc/Module/Install/WriteAll.pm
+SHA1 46730854dc7241dc334b546eef267fde8df24aea examples/Example-Todo/lib/Example/Todo/Model/Todo.pm
+SHA1 61d12c9d3bb174aad4856349686c9e71e75fa7e0 examples/Example-Todo/t/00-model-Todo.t
+SHA1 3b22513afb560789fb0f38f50c55249d70f1b06d examples/HelloKitty/Makefile.PL
+SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 examples/HelloKitty/bin/jifty
+SHA1 dd97d225e86ab1cb13eabaab12a9b1bfb2410cff examples/HelloKitty/etc/config.yml
+SHA1 24d7e3ade49a5a3a7dd4f2dd74e836bafcbbbedf examples/HelloKitty/hellokitty
+SHA1 2ac96cfdb02f3a3fe5550ceb0442d9a30f7120c9 examples/HelloKitty/lib/HelloKitty/View.pm
 SHA1 4db882e66864fa40a6532ce5b83699839804b062 examples/MyWeblog/Makefile.PL
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 examples/MyWeblog/bin/jifty
 SHA1 d1394cef410a14394a05e2a6e6a9b32c059cb5d6 examples/MyWeblog/etc/config.yml
@@ -87,122 +115,165 @@
 SHA1 242c000d466ce6782ac759b7baea86c3b4c902bd examples/MyWeblog/t/00-model-Post.t
 SHA1 37ff983ec74bee20ce6a6425e2cbd2effa55e586 examples/Ping/Makefile.PL
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 examples/Ping/bin/jifty
-SHA1 2630087e4914b7d8a7fa8bea82e778fab51735dd examples/Ping/etc/config.yml
+SHA1 a86e4873a4c6be33cf919be8cbbf4b0990720b7e examples/Ping/etc/config.yml
 SHA1 9b143bab7499c4ebde34e88e635a59bd205a1bf0 examples/Ping/lib/Ping/Action/AddPing.pm
 SHA1 fc630086e84277cf19a9e9eb382c79e41d0dd810 examples/Ping/lib/Ping/Action/CancelPing.pm
 SHA1 918d401c046480483ca935728529e016de6d73f6 examples/Ping/lib/Ping/Event/Pong.pm
 SHA1 ba3f1840a56742c011e96890a327ccbe7ecb3a4d examples/Ping/lib/Ping/PingServer.pm
-SHA1 85e03a9df32331e713be7d637c04fa3ca1a24626 examples/Ping/lib/Ping/Server.pm
 SHA1 dc0966379ee2dc74c10ee8d5688cec5b1db17ac4 examples/Ping/share/web/templates/fragments/pong
 SHA1 05ac283a14e76750d63678d0864a0403aa18fd28 examples/Ping/share/web/templates/index.html
 SHA1 53c8822ddf426e82fe239e4470574913411b1355 examples/Ping/t/00compile.t
 SHA1 6d6c378447f9d74d53c06a2a027736b48b5d0670 examples/Ping/t/01startup.t
 SHA1 603bb9de29fb8cba7f13409c546750972eff645d inc/Module/AutoInstall.pm
-SHA1 9b2f9d83bcf77860f53a0c07c90a4a59ad9f5df1 inc/Module/Install.pm
-SHA1 ad955f51ad2c40d4ba35395c27f5ed899a80bf7a inc/Module/Install/AutoInstall.pm
-SHA1 abe32855d75ab13747cf65765af9947b7a8c3057 inc/Module/Install/Base.pm
-SHA1 95b81d1e91bd634467bf633571eff4420e9c04eb inc/Module/Install/Can.pm
-SHA1 1fe98c63cf9d7271c8cb4183ba230f152df69e26 inc/Module/Install/Fetch.pm
-SHA1 0606a8b02a420600bc3e2b65ab82f70266784926 inc/Module/Install/Include.pm
-SHA1 2249171a2b72cd73ff2c0a06597d29f86e5df456 inc/Module/Install/Makefile.pm
-SHA1 381bb98ea3877bba49ae85e7a7ea130645fd3dbf inc/Module/Install/Metadata.pm
-SHA1 b384bd42bc6263dc56d04a884ef4e5fe340049f8 inc/Module/Install/Scripts.pm
-SHA1 fcae3a3bda09e6ba955c8746c2bdf582a23b8d56 inc/Module/Install/Share.pm
-SHA1 0c2118868ef82ac517eb6d9c3bd93e6eb9bbf83e inc/Module/Install/Win32.pm
-SHA1 e827d6d43771032fa3df35c0ad5e5698d0e54cda inc/Module/Install/WriteAll.pm
+SHA1 ceac99579ef3914de1936417282842c07d907a6a inc/Module/Install.pm
+SHA1 c289fbaf0a2bce39c4993dab38fc70cbb3789f57 inc/Module/Install/AutoInstall.pm
+SHA1 6c9471c92c28e247fb84f4ab7dc277f68b33ea95 inc/Module/Install/Base.pm
+SHA1 b2cb1026330e8c4f8533c79569498ab15f189d86 inc/Module/Install/Can.pm
+SHA1 78acbad45c4289c228ead2278fc213ddd66bcead inc/Module/Install/Fetch.pm
+SHA1 a4b4488af13b5d038bb6fbd3c4ec635d2c640567 inc/Module/Install/Include.pm
+SHA1 642e5b27f4cbbbe440e5dc05c639f5fb79875fe3 inc/Module/Install/Makefile.pm
+SHA1 80d024f3eccf1c825b02b5e59de236b0af7d4bfc inc/Module/Install/Metadata.pm
+SHA1 a748c6176a996e5f32c50f2c49670a8ce532fb71 inc/Module/Install/Scripts.pm
+SHA1 f763d4fe06ca0876fa047a719c2fcf110a92b1d0 inc/Module/Install/Share.pm
+SHA1 fe6780ea5cfd67c79140699fbd4f0fe262255d57 inc/Module/Install/Win32.pm
+SHA1 51d43bffcfd7ffdecb8c8e9f97f3896c31b2e1b2 inc/Module/Install/WriteAll.pm
 SHA1 c17e8f3cf8ebe1eb4929fd2bd2fd530a9de1abd0 lib/Email/Send/Jifty/Test.pm
-SHA1 9380a1872911cf469d08049e4c76645eecef63f8 lib/Jifty.pm
-SHA1 f2db715c8a15d0c7c5c7cf30511dac6547f72fc5 lib/Jifty/API.pm
-SHA1 25ed41c1b89c6d39a8e6d027a9120b3e35785951 lib/Jifty/Action.pm
-SHA1 a6d9d87b4fa06cfab36f249a67946b45669dcee7 lib/Jifty/Action/Autocomplete.pm
-SHA1 19147544734762a243ba7e8b603168930aad9c62 lib/Jifty/Action/Record.pm
-SHA1 39d9bca03c6502e128b453fe3bda5e1d4173f343 lib/Jifty/Action/Record/Create.pm
+SHA1 0eb6271f949efa613d516c73cb672f7392c336b5 lib/Jifty.pm
+SHA1 337627c441c5639405a2d2cc751c63616d25c221 lib/Jifty/API.pm
+SHA1 7dc39eb45149bd3c9b7e1f19047657dbf84688df lib/Jifty/Action.pm
+SHA1 d73654ad2f7edc2f1661ab866b1db609d83806b3 lib/Jifty/Action/Autocomplete.pm
+SHA1 a96809977dac6f6c644b4b265ce510c13130264c lib/Jifty/Action/Record.pm
+SHA1 9afca5c5a9b57f11eb276afadea614b1be4570f6 lib/Jifty/Action/Record/Create.pm
 SHA1 224f3ed1a4710fb13e4627acd22067e2fa5c35c6 lib/Jifty/Action/Record/Delete.pm
 SHA1 1e400299405a06d3d09bb7548d97c52b850b7f43 lib/Jifty/Action/Record/Search.pm
 SHA1 821d06cdd92876efd01e08800eae46e52e13c2a6 lib/Jifty/Action/Record/Update.pm
 SHA1 ab7a0e0bae4cd1ecbda260b339a4116e65708a7f lib/Jifty/Action/Redirect.pm
-SHA1 cf349fcfe9ee28216eae2213ab0016ceaffaf2a7 lib/Jifty/Bootstrap.pm
-SHA1 f6e9cb12da25b65df8bc2762423d1fcc9d41ec3e lib/Jifty/ClassLoader.pm
+SHA1 0334c7ad4458bca073fa22372b4775937a0852e1 lib/Jifty/Bootstrap.pm
+SHA1 7a3849fb30ecb9bb7c0c382b7cc44b6216516de2 lib/Jifty/ClassLoader.pm
 SHA1 1009fa942a8cf3da853694f321d6f67d70613a79 lib/Jifty/Client.pm
 SHA1 a4e91b327848fe1c5b76e4ffaa926300e4c1ef2f lib/Jifty/Collection.pm
-SHA1 ce2f398600582262a2f5562a1de77bc03f6e2676 lib/Jifty/Config.pm
-SHA1 48514a496198c022aff7e4d1c578824addda7c91 lib/Jifty/Continuation.pm
-SHA1 15970f85b57eab885568a71f164dc627c791287c lib/Jifty/CurrentUser.pm
-SHA1 4521a0e9a145697c836e2247fbdb4e93b8966366 lib/Jifty/DateTime.pm
-SHA1 9595652e061d4066615b1ac811700da46394ea65 lib/Jifty/Dispatcher.pm
+SHA1 70ed11fa2fe5a196b5d5ee18e162e0f561dc7780 lib/Jifty/Config.pm
+SHA1 c6d8ac5f2dc450636478bc3051724f7eac74fce6 lib/Jifty/Continuation.pm
+SHA1 3fc7f4db180481c109248941a65f224c8e346aa8 lib/Jifty/CurrentUser.pm
+SHA1 c3ee8cd867481561dd7359d8f609687746e3b5dd lib/Jifty/DateTime.pm
+SHA1 24425ca3e82abf17e15182b8e13240d9ab102b47 lib/Jifty/Dispatcher.pm
 SHA1 c9c904906c35def343f14c0c216b62771c07f842 lib/Jifty/Event.pm
 SHA1 fb9f33e2838fbff0cd5b5a784adee8b0fc347ebc lib/Jifty/Event/Model.pm
-SHA1 5a6b765e4e61e1a098cc997127c9a5e9405ea32d lib/Jifty/Everything.pm
+SHA1 121cc604741f5a674cbbc2a55dfb6d4c8cf11bb8 lib/Jifty/Everything.pm
 SHA1 818bd0aa6afeb39bf96e0068fe3222c74133b4d8 lib/Jifty/Filter/DateTime.pm
-SHA1 8f83cbce4937acba8d2f5c944d3d3a95a0156d9c lib/Jifty/Handle.pm
-SHA1 0c5f2e31fc9cdd266ff3c10bc3ff6715a3b77c9d lib/Jifty/Handler.pm
-SHA1 89fb4f3164b4ea84eb8084829bbca9e93d2259b1 lib/Jifty/I18N.pm
-SHA1 7ce311e2005ef0df27d71b1d80a4f05237dda9f4 lib/Jifty/JSON.pm
-SHA1 3af93349fe8a236c714d88367077f88af11f5d32 lib/Jifty/LetMe.pm
-SHA1 f76b940651eb2c53bce0af9be451a24b0358fec9 lib/Jifty/Logger.pm
-SHA1 858723b0874be436d44be113934f182eff7e9388 lib/Jifty/Manual/AccessControl.pod
+SHA1 45fa3790eb4737497dd728510cc92aa76017e350 lib/Jifty/Handle.pm
+SHA1 947e5aee7b981e19042f3343050a129600b88772 lib/Jifty/Handler.pm
+SHA1 c413c80506fe0a1da3154739249a9351982b1db2 lib/Jifty/I18N.pm
+SHA1 fe370e2c51ca0f20cb0bce133b8c9067c02a524a lib/Jifty/JSON.pm
+SHA1 93d009a7d9a25975786b9ded3dcd5fdac90c9389 lib/Jifty/LetMe.pm
+SHA1 1687a979438f24c95a6b857ab5305910108bfb49 lib/Jifty/Logger.pm
+SHA1 9a01a2e586aa5799fdc0f04c6240220d9dd953b9 lib/Jifty/Manual/AccessControl.pod
 SHA1 ef9ff36385a9f780ac0204bffb9425818d78b789 lib/Jifty/Manual/Actions.pod
 SHA1 d320630f6613f4aa1ec3b9537129fd9ca847fb61 lib/Jifty/Manual/Continuations.pod
-SHA1 976198d6f93f9c46625c3fd1bd9d89a13ab89f40 lib/Jifty/Manual/Cookbook.pod
+SHA1 99848cf166e90d9c0963a65d09a627ba11a3613e lib/Jifty/Manual/Cookbook.pod
+SHA1 ace7259a8fc39a43174e3292a8003baa43670da8 lib/Jifty/Manual/Deploying.pod
 SHA1 38a90072f4a25eac8d4480b00290b069e6397673 lib/Jifty/Manual/FAQ.pod
-SHA1 0f95658ca3d4ed3deb1951f514774446a583247f lib/Jifty/Manual/Glossary.pod
+SHA1 910f64961a65608ab8575a08aa4eab6b1862579b lib/Jifty/Manual/Glossary.pod
 SHA1 f272be20cc67acaf01c116f432a8f42d82c57877 lib/Jifty/Manual/Models.pod
 SHA1 1204d70c868084ac3114fae277e98a756f83f819 lib/Jifty/Manual/ObjectModel.pod
-SHA1 537017160a444f84bf1673cc3722db644c2b662e lib/Jifty/Manual/PageRegions.pod
+SHA1 60ee994e58dfb4e9190badc16c96c4760e5669cb lib/Jifty/Manual/PageRegions.pod
 SHA1 8ba19a0760196ceb1afbeaa06e7314e254bef258 lib/Jifty/Manual/RequestHandling.pod
 SHA1 11c2a307f398203ebd804cee990a89e940c406f6 lib/Jifty/Manual/Style.pod
-SHA1 69c995fe4da233dc1b54655813cb6e51d979b759 lib/Jifty/Manual/Tutorial.pod
+SHA1 6920f173d2460fed1957019be295acb588fff9a1 lib/Jifty/Manual/Tutorial.pod
+SHA1 bfdb8da4b149a60d30700a7494e67ea7367a9417 lib/Jifty/Manual/TutorialRest.pod
 SHA1 4ad61c8957fdfed1aa5cc60294cbfb43a359e2d2 lib/Jifty/Manual/Tutorial_de.pod
 SHA1 45f95f61826365d39a5eab2cc119967273d17077 lib/Jifty/Manual/Tutorial_ja.pod
-SHA1 0398a7d053b6c78f7d769f7251d3a01af80cbe57 lib/Jifty/Manual/Upgrading.pod
+SHA1 2b4c79b6656658b7198ba579b58e3a599d404b01 lib/Jifty/Manual/Upgrading.pod
 SHA1 d0b7a4277c8a3d1a393d7c51fff48b059461f87c lib/Jifty/Manual/UsingCSSandJS.pod
 SHA1 59ce74460e9c1fe8aa1114c2e874348583b76548 lib/Jifty/Mason/Halo.pm
-SHA1 809ace5bafff5ad2461d5495464863ba808dfd19 lib/Jifty/Model/Metadata.pm
-SHA1 36de25464ae4eb07675f453cc590b634c6ff5a37 lib/Jifty/Model/Session.pm
+SHA1 c7a9988b0826f9c55af2415c7d314ff546193cee lib/Jifty/Model/Metadata.pm
+SHA1 4b89786af61d1490286bc02c4c3a8edb95aa0b60 lib/Jifty/Model/Session.pm
 SHA1 0efcdf22d66e521cf250c1398caf3aba93ed795d lib/Jifty/Model/SessionCollection.pm
-SHA1 e24506b3e0fbdb450e55f3935980813c9c9e2bee lib/Jifty/Module/Pluggable.pm
-SHA1 f0090580d6a54fd8114b8fc1b4cb644c8c3dd2f5 lib/Jifty/Notification.pm
+SHA1 d15fc44fc8af2c4a7db3c2f08e1d69d6f397e734 lib/Jifty/Module/Pluggable.pm
+SHA1 f7c511c6b0c6ccfc3c5fdc0bf0a4e224d78a9c40 lib/Jifty/Notification.pm
 SHA1 7223070583b1b15f651db7a71b97e039e084aa4f lib/Jifty/Object.pm
 SHA1 c3fde2a862013cd6284637d79c751c3c2e360720 lib/Jifty/Param.pm
-SHA1 11d4de5da85ee53e6f3f434a5a519ebc574cedab lib/Jifty/Param/Schema.pm
-SHA1 69708ae740a40953c50217c37e23740179da80be lib/Jifty/Plugin.pm
-SHA1 d80065a87ec1dd8b0bbcd1853e9a7192a18a04f5 lib/Jifty/Plugin/ClassLoader.pm
-SHA1 20d3f35b391236d9a0e554e62368b4f6fd1383dc lib/Jifty/Plugin/REST.pm
-SHA1 690d1ca831e42d1b1810875abdbae0ff480620e2 lib/Jifty/Plugin/REST/Dispatcher.pm
-SHA1 3fccef02727c8e75a0b4c93f940e9e18e0a499d4 lib/Jifty/Record.pm
-SHA1 0283384c06b36339143690b4beb7830ab4648e0f lib/Jifty/Request.pm
+SHA1 c4c0387640f7eafb35b346798c5e150c6ecb7496 lib/Jifty/Param/Schema.pm
+SHA1 134c5535e4b1f5ef0a5a8f78259b36c4bf247bed lib/Jifty/Plugin.pm
+SHA1 328b724a1f266999eb1f12e60a7ac6fcc533d177 lib/Jifty/Plugin/AdminUI.pm
+SHA1 00354893bf1283e9cf1b52de5b41bdfb57a78811 lib/Jifty/Plugin/Authentication/Password.pm
+SHA1 9f078a684545d3a9c075d83812cffeca0a3b633e lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm
+SHA1 de9208f8911bc09594299b618a7ce05c71cac57e lib/Jifty/Plugin/Authentication/Password/Action/GeneratePasswordToken.pm
+SHA1 2da111cb0154fe09287b9c8db251b5d8720d0379 lib/Jifty/Plugin/Authentication/Password/Action/Login.pm
+SHA1 3ccf33cfd732343cfeeda7f2acc1df7c7da721fe lib/Jifty/Plugin/Authentication/Password/Action/Logout.pm
+SHA1 074fe2fa59464a78b69558f2c20b39fe45a6e56e lib/Jifty/Plugin/Authentication/Password/Action/ResendConfirmation.pm
+SHA1 eb20b698db12db185f08e4d0e0a6c39dc2c1432f lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm
+SHA1 89d74967f85b631644d039393920646cfb772f2a lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm
+SHA1 28604b89817992c647042420090a59fee0fe06bd lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm
+SHA1 3d0b444280c3b0ae577e0ada5cb3fd2eb8803f9f lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm
+SHA1 b0ccc1d001aeca18ad7466b531081805408b2010 lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm
+SHA1 3191af60483a20faf1d624da37929e3310ced14c lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm
+SHA1 9711ece6f3637e972708c8bda313aaa57fd1b405 lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm
+SHA1 f8e1724e5d0d3e490439f0ad761a96155ff1b5a4 lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm
+SHA1 91272a6c9926cdacbfc10afe8624a35868a8e8be lib/Jifty/Plugin/Authentication/Password/View.pm
+SHA1 da70c7fbcd78d7ae9bd53deb74a022d0eeea4a12 lib/Jifty/Plugin/ClassLoader.pm
+SHA1 25d4c8b9459c9c299fb181d41539475a854309f0 lib/Jifty/Plugin/CompressedCSSandJS.pm
+SHA1 3b6cb101e9e3465cefdb843fb9108cb126644284 lib/Jifty/Plugin/CompressedCSSandJS/Dispatcher.pm
+SHA1 b6a34618e94885dac38d0a6b501a63f5c0184008 lib/Jifty/Plugin/ErrorTemplates.pm
+SHA1 07037bce896482134852dcfb6c15a8bbb8fa6adc lib/Jifty/Plugin/ErrorTemplates/View.pm
+SHA1 f13f769cb4d6d529bcfc46647512544eaaa54774 lib/Jifty/Plugin/Halo.pm
+SHA1 432d5c6343b4390dcd135918d7f729d2c01eee5c lib/Jifty/Plugin/LetMe.pm
+SHA1 8692eb8735e17f6f9a25f41c368da4a6839363c8 lib/Jifty/Plugin/LetMe/Dispatcher.pm
+SHA1 af733b25eee3cc4e0e6b087a76bfd965534a2343 lib/Jifty/Plugin/OnlineDocs.pm
+SHA1 fcc3ccbee7c9646745fc79475d53f67e81d7c0db lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm
+SHA1 df332565b291fd458fab232414b24283f379ac16 lib/Jifty/Plugin/REST.pm
+SHA1 053b6f7d44ade4ed7567a4a0c444e777108b26c3 lib/Jifty/Plugin/REST/Dispatcher.pm
+SHA1 7fa0c5fa1ef6dbe8f1c4a351133f74ca32a70507 lib/Jifty/Plugin/SkeletonApp.pm
+SHA1 1b07ce39502e28564f41d8dd27a4c0094de9f354 lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm
+SHA1 81362e19c903ba6c98c3cd84bc7b4b8f5615d05e lib/Jifty/Plugin/SkeletonApp/View.pm
+SHA1 a51b4791f28c6f64ba00ac21fc05933b32e19015 lib/Jifty/Plugin/User.pm
+SHA1 a1c827266b0db910b02476eee76f6a5a4663e2ba lib/Jifty/Plugin/User/Mixin/Model/User.pm
+SHA1 c77500585cddf1c520b0438384481a1b68d13c57 lib/Jifty/Plugin/Yullio/View.pm
+SHA1 26b636ef6291098364119287e7363be9f58990f7 lib/Jifty/Record.pm
+SHA1 8ba38d25e9f6ead360e20baa457f119694584edd lib/Jifty/Request.pm
 SHA1 7e4d83147f5f665bb0e8d290ea70340b82a205c2 lib/Jifty/Request/Mapper.pm
 SHA1 0a92b4cdb402463e303b897195c9ad914767c27f lib/Jifty/Response.pm
-SHA1 56988d89d24e33a5ed2c2c6539b02593cc9e3344 lib/Jifty/Result.pm
-SHA1 85de033731ae63d0b3efec515a3608337cbc5c31 lib/Jifty/RightsFrom.pm
-SHA1 0306af64a6289796db4b5ff2b8c5e7c23506a9e3 lib/Jifty/Script.pm
-SHA1 a576b768487f81889ade60cb10f89eb2073adadc lib/Jifty/Script/Action.pm
-SHA1 17bb02c22e126df9ff783843e5921e46b060c2be lib/Jifty/Script/App.pm
+SHA1 669b0956c14105b4178875d6856b129b75941328 lib/Jifty/Result.pm
+SHA1 126fb131c36f6ff7dc6cc4193b0c9a402168a832 lib/Jifty/RightsFrom.pm
+SHA1 83f1a04d22cb553f0af2842b7fe603277441f72b lib/Jifty/Script.pm
+SHA1 f97fb67cd7db7aa2374ef4a0f1b8b9705e3ce153 lib/Jifty/Script/Action.pm
+SHA1 3aa3a449b282e05dfb312cf266572edabf2bae17 lib/Jifty/Script/Adopt.pm
+SHA1 84a9ddd8c2f9d738daed65201ae938cb5e0a45de lib/Jifty/Script/App.pm
 SHA1 1ad9937d9e28f1568954bcffac500be87f3cb355 lib/Jifty/Script/Deps.pm
-SHA1 cb42aff8740412f9e7a26915a4e852817aa39af8 lib/Jifty/Script/FastCGI.pm
+SHA1 3c26ea2d6e25c42ecd7edae41d4ad2fc552f1451 lib/Jifty/Script/Env.pm
+SHA1 79fbed4c7b6e3b85cd78afbc69bd990f45f97a01 lib/Jifty/Script/FastCGI.pm
 SHA1 e25a259fc9fd3183a7981236f428f54ac4c4f49e lib/Jifty/Script/Help.pm
-SHA1 be1f648841609388f48214e632e0b169216dd58a lib/Jifty/Script/Model.pm
+SHA1 29d16baf7dbf778f6082f8852723b6ef82842ef0 lib/Jifty/Script/ModPerl2.pm
+SHA1 ae7d6a97f55a111e10cbc127d3174c48dc896afc lib/Jifty/Script/Model.pm
 SHA1 77c221bb4b7162b2fc95c841ceeea04194afb264 lib/Jifty/Script/Plugin.pm
-SHA1 eba3c96bcfae42ea6a9e5d2cbef6bca19617b47e lib/Jifty/Script/Po.pm
-SHA1 afb4c37e7503e53676773bb3d6f65fde111679fc lib/Jifty/Script/Schema.pm
-SHA1 4bbe2362a6cd195fac119a37cd71119afb5516f6 lib/Jifty/Script/Server.pm
-SHA1 0646a96ca5f3da1585e3fb1dcc9b3540d2b8f50f lib/Jifty/Server.pm
+SHA1 3365d06f92ffe40175f2c9d7fa4175c48cd42ed9 lib/Jifty/Script/Po.pm
+SHA1 cf7d62a4634d32342e5b4581ceb1dc8c78439943 lib/Jifty/Script/Schema.pm
+SHA1 50e6a73afeb945145576c079d14d3707d13b4344 lib/Jifty/Script/Server.pm
+SHA1 48a8889b44c0450ccb2d27cbb0b7c7f3ae26a426 lib/Jifty/Server.pm
+SHA1 b49ae221b107519b3019b3f5e5ab5b7e8c6b4332 lib/Jifty/Server/Fork.pm
+SHA1 9a8c2f2cdc88fc00baaafaa72bc3413e086c0448 lib/Jifty/Server/Prefork.pm
+SHA1 e7453a3cda290e60d5432e60e53bec8b92a91772 lib/Jifty/Server/Prefork/NetServer.pm
 SHA1 4c51d2df15281788b74d080488b0c5959cd95a1a lib/Jifty/Subs.pm
-SHA1 43277d31da2a30afd160dbe2077314285898438f lib/Jifty/Subs/Render.pm
-SHA1 df6cadbfbd91dcbf91d334a2132882821d9b3741 lib/Jifty/Test.pm
-SHA1 24eb481ac109ce0639496d6e16311ae2af0bb0da lib/Jifty/Test/WWW/Mechanize.pm
-SHA1 bacce10076cd7790405d29b0cabd99cae06b739e lib/Jifty/TestServer.pm
-SHA1 206e12811205063b22fcaaf0cd04dd66321d793c lib/Jifty/Upgrade.pm
+SHA1 b3d122eed10c4ac3cba561913a42220c2f5ee085 lib/Jifty/Subs/Render.pm
+SHA1 e15bde68ba67b141ae1565be066f1e1f171f63ec lib/Jifty/Test.pm
+SHA1 0d6d53b5084bb89baea771d3e9d602a195255e37 lib/Jifty/Test/WWW/Mechanize.pm
+SHA1 47c5840fafd56473a0e1a9228f169d3813317c13 lib/Jifty/TestServer.pm
+SHA1 4614193951790ed53fc8682135cdb1b40d3fa975 lib/Jifty/Upgrade.pm
 SHA1 f3957ac04ad92737d68b2a63f068679b4bacafed lib/Jifty/Upgrade/Internal.pm
-SHA1 01e8cf19fef0094b917712165d5ae0acf37fa31d lib/Jifty/Util.pm
-SHA1 bf4cbc6a7c94597cadb101b609f80004bfb64eef lib/Jifty/View/Mason/Handler.pm
-SHA1 91b4185b0570453805f15b0eb0ce0f50a6f1eef3 lib/Jifty/View/Static/Handler.pm
-SHA1 1b62b886ec2a10b9b078535a7782bd01507bf6a6 lib/Jifty/Web.pm
-SHA1 93f70b329f4e05105edd6a2bacb1d71ed59c5449 lib/Jifty/Web/Form.pm
-SHA1 07cea2d1e0075a331d4f028fee34c5fd1bdda618 lib/Jifty/Web/Form/Clickable.pm
-SHA1 9065dcef2d3e755bcefbc5ec1481bf92e883c287 lib/Jifty/Web/Form/Element.pm
-SHA1 f7b910dc62f6265d4df1a8ec937d902549f1ee49 lib/Jifty/Web/Form/Field.pm
-SHA1 ba87c27d5432a8393ffeaf39323ac80c0f4facab lib/Jifty/Web/Form/Field/Button.pm
+SHA1 d42ff4531e36438208cd8242d15f7d210928ff6b lib/Jifty/Util.pm
+SHA1 05af258e63bbb8ea166e845b8028546b858fcecb lib/Jifty/View/Declare.pm
+SHA1 dd7596d3d4cc8df03c074a44a0cd0813a5cf0a89 lib/Jifty/View/Declare/BaseClass.pm
+SHA1 912220dc62ae0d21d78ed499626a235a14db09a6 lib/Jifty/View/Declare/CoreTemplates.pm
+SHA1 88c62ed42916e58a344e1d09e9a0019436e34cb6 lib/Jifty/View/Declare/Handler.pm
+SHA1 bba1390f47745aa843a72565fbdf1adce3afd241 lib/Jifty/View/Declare/Helpers.pm
+SHA1 1df8f813bdc979dd182a455e9953254abcd247ed lib/Jifty/View/Mason/Handler.pm
+SHA1 2e97fd90420ade1dcdc6d5b815a352cd83c23671 lib/Jifty/View/Static/Handler.pm
+SHA1 94172b92971ea2a5fcdc3f11ebcc94a8274688c6 lib/Jifty/Web.pm
+SHA1 5dbb5f45d0ff0e0ddfabe91d6152c1aa507dbc9b lib/Jifty/Web/Form.pm
+SHA1 f073670eb2f206f99bd1f1377740965cd5da5ac1 lib/Jifty/Web/Form/Clickable.pm
+SHA1 d77f222ad036fe8b39715c85fab009b7a283e1b9 lib/Jifty/Web/Form/Element.pm
+SHA1 a823ab5fae50fa6222c4d3143779d2288e1cc3da lib/Jifty/Web/Form/Field.pm
+SHA1 bb9dc120af472abe3a35f89c772728c75ed8a3c2 lib/Jifty/Web/Form/Field/Button.pm
 SHA1 c1071263839a663d44d7f922c7c24b5bcc132a82 lib/Jifty/Web/Form/Field/Checkbox.pm
 SHA1 b21ef4e33a628f5d6c54adf5f47f75e69a861644 lib/Jifty/Web/Form/Field/Combobox.pm
 SHA1 cc86a97a80c6c9e22183a099979a712a3900a39a lib/Jifty/Web/Form/Field/Date.pm
@@ -217,10 +288,11 @@
 SHA1 2548412d5bfbd08050d53ab5c58e0d962d4b2448 lib/Jifty/Web/Form/Field/Unrendered.pm
 SHA1 e37541952c969f2e74f942782d483de75e9265f9 lib/Jifty/Web/Form/Field/Upload.pm
 SHA1 16cff04150ba0ae8bffe04c1c661d80972876248 lib/Jifty/Web/Form/Link.pm
-SHA1 e4baa13068c7de8e4737efa4dbc18f1f059e6047 lib/Jifty/Web/Menu.pm
-SHA1 e17189fe3d525c4fe2a251db20a5a6eabbc7c786 lib/Jifty/Web/PageRegion.pm
-SHA1 093ab860163f03e9d85c8bb366d694830b7d940a lib/Jifty/Web/Session.pm
+SHA1 a4787c85a11c091f8560d1960edce1aaeeced2c9 lib/Jifty/Web/Menu.pm
+SHA1 e912f7c224380aaf79c6cece6219670a973fe85e lib/Jifty/Web/PageRegion.pm
+SHA1 0fb24e6615e89b7f3b2b0af7457c4aaa61a48ad9 lib/Jifty/Web/Session.pm
 SHA1 f655fb9734715ebf51fb5e9b554c02b9e4e2ac61 lib/Jifty/Web/Session/ClientSide.pm
+SHA1 d7a8f92ddbc614904ad6aa53d818b0bd5df03317 lib/Jifty/Web/Session/None.pm
 SHA1 c4de1ef964243aae5ab90d0a5a6dd9c213eb9f80 lib/Jifty/YAML.pm
 SHA1 feeb00d6502ca54367036767f5e3f20275580291 plugins/AuthCASLogin/MANIFEST
 SHA1 f7ee4953b3c05710fe531cc9b579f65ed04af761 plugins/AuthCASLogin/Makefile.PL
@@ -237,21 +309,20 @@
 SHA1 36215b6306dd37ebbf6206f526e9464d2d261d2a plugins/AuthCASLogin/share/web/templates/caslogin
 SHA1 f971aec45ba679dc55a9955077324f5c0ea75cca plugins/AuthCASLogin/share/web/templates/caslogout
 SHA1 c93e6f367c6a110cb05f8fefa4cb37881daeebe7 plugins/AuthCASLogin/t/00-load.t
-SHA1 96e2b7d839f54a14c42dd421516a267d7e2c4b94 plugins/AuthCASOnly/MANIFEST
-SHA1 62ee3ecfa8b4923ee68aa5f3179f2b3c5c8551dd plugins/AuthCASOnly/META.yml
+SHA1 215e0e0faa081e206560b09cf4570ab949b298a9 plugins/AuthCASOnly/MANIFEST
 SHA1 9e218ee17e541c947ceb6f78d4714fc4baa43895 plugins/AuthCASOnly/Makefile.PL
-SHA1 0211277b86a7c26952a44da5ea55945a32ca2689 plugins/AuthCASOnly/debian/changelog
+SHA1 a21e7eea5a3b6a3b129c0e8d0ebb87d6b4af86a3 plugins/AuthCASOnly/debian/changelog
 SHA1 9c6b057a2b9d96a4067a749ee3b3b0158d390cf1 plugins/AuthCASOnly/debian/compat
 SHA1 df5baa3318d61d253b6256a2a3abb06aa28669a5 plugins/AuthCASOnly/debian/control
 SHA1 c361200ede7340a93f131034eaaaa71f36bf1617 plugins/AuthCASOnly/debian/copyright
-SHA1 6178f211c12057c7f8bf110ae4d9ae9961ba90c7 plugins/AuthCASOnly/debian/files
+SHA1 dda59a9600b41022496d69c03b2d7eb9106705fa plugins/AuthCASOnly/debian/files
 SHA1 df2b684174a5e8bdf6d14b985020057702b4c884 plugins/AuthCASOnly/debian/rules
-SHA1 e324ade45843a878b10cc5bd78061401dcf56685 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly.pm
+SHA1 919c785814ab3c9f848f89b44184fe599d58fe74 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly.pm
 SHA1 827a868f825e94c7630368d4cd98d591edacc188 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Action/CASLogin.pm
 SHA1 cc9279734210b6a8de3312716ee36868d437f7db plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Action/CASLogout.pm
 SHA1 b401b903bece0f11a45c7fe129ada9e6e2681f4b plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/CurrentUser.pm
 SHA1 d0a159254cb3d99a5d3664ffd8c8d42c3daa40f1 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Dispatcher.pm
-SHA1 67aea2e30d74af4e01b66ef5bebb4d69d78f2b37 plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Model/CASUser.pm
+SHA1 263c412cfe48db61500f5566a0174fbb284e46fd plugins/AuthCASOnly/lib/Jifty/Plugin/AuthCASOnly/Model/User.pm
 SHA1 36215b6306dd37ebbf6206f526e9464d2d261d2a plugins/AuthCASOnly/share/web/templates/caslogin
 SHA1 f971aec45ba679dc55a9955077324f5c0ea75cca plugins/AuthCASOnly/share/web/templates/caslogout
 SHA1 de334fd98ec8b7bf6b72b9f4d98da1405f2fd9a9 plugins/AuthCASOnly/t/00-load.t
@@ -271,19 +342,19 @@
 SHA1 a52f49740c6a0c5dfb5ef2413b26d40c71e8dba0 plugins/AuthLDAPLogin/share/web/templates/ldaplogin
 SHA1 f971aec45ba679dc55a9955077324f5c0ea75cca plugins/AuthLDAPLogin/share/web/templates/ldaplogout
 SHA1 43c8998946172ac32eeefdfbf95a663d6e60e40a plugins/AuthLDAPLogin/t/00-load.t
-SHA1 8c487e541a3d5115e8b04f35ac6555cca05de933 plugins/AuthLDAPOnly/MANIFEST
+SHA1 56ea69fc320fe797b3ee0abe744e838783156e38 plugins/AuthLDAPOnly/MANIFEST
 SHA1 76658d43f96759a30895e9ab9116d3fe2ec475bf plugins/AuthLDAPOnly/Makefile.PL
-SHA1 6490648ff1114d79ba05a70e8106d5d0226d72ae plugins/AuthLDAPOnly/debian/changelog
+SHA1 03bd8afc22d6fc4dfadf240f683004d5d1cf7261 plugins/AuthLDAPOnly/debian/changelog
 SHA1 9c6b057a2b9d96a4067a749ee3b3b0158d390cf1 plugins/AuthLDAPOnly/debian/compat
 SHA1 e256f776a58f8ca1de7a20082e855e03bace79d8 plugins/AuthLDAPOnly/debian/control
 SHA1 c361200ede7340a93f131034eaaaa71f36bf1617 plugins/AuthLDAPOnly/debian/copyright
 SHA1 68dfa9d87a39ca9c6480d8a93e7efb18565b4db3 plugins/AuthLDAPOnly/debian/rules
-SHA1 69f53febd6a99e6e61e5b87a387139a74f509b8d plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly.pm
+SHA1 3bd9e35fc165eddb6d6f007bfda1d18dc45855e5 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly.pm
 SHA1 3a1a5ac6571c49fd766eba8f8fb94dbc35081192 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Action/LDAPLogin.pm
 SHA1 8709ec6fd348b2229eecab4778fe52b9e3f5f241 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Action/LDAPLogout.pm
 SHA1 5776159e43fe28077ebe66359d888620c1a78c30 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/CurrentUser.pm
 SHA1 11063de8ce0267140e4eeacc8caa552de893d435 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Dispatcher.pm
-SHA1 be8d85f7423aabd9e504feb4e759d412990c4f5a plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Model/LDAPUser.pm
+SHA1 a03143b94d7abae6c6b162b4353c9eb7ddaf2143 plugins/AuthLDAPOnly/lib/Jifty/Plugin/AuthLDAPOnly/Model/User.pm
 SHA1 645c578bde4a89f2a47ffbff048863a52691ad11 plugins/AuthLDAPOnly/share/po/en.po
 SHA1 42fa3dbdbfd9c34dd1260df7d70fd215aeb3d987 plugins/AuthLDAPOnly/share/po/fr.po
 SHA1 a52f49740c6a0c5dfb5ef2413b26d40c71e8dba0 plugins/AuthLDAPOnly/share/web/templates/ldaplogin
@@ -293,11 +364,13 @@
 SHA1 0086fe18fd01b6ace92636034ea606008ab5a374 plugins/AuthzLDAP/Makefile.PL
 SHA1 d9d714781bef6a0e3892f258350f9d6797eafa9a plugins/AuthzLDAP/lib/Jifty/Plugin/AuthzLDAP.pm
 SHA1 a63d50ed4f93a1d9909af9889fc30d8b3e9140a4 plugins/AuthzLDAP/lib/Jifty/Plugin/AuthzLDAP/Action/LDAPValidate.pm
-SHA1 5b391191e624c0d2e8c16f19c531a2c2993ba49e plugins/AuthzLDAP/lib/Jifty/Plugin/AuthzLDAP/Model/LDAPFilter.pm
+SHA1 b43a3b2208f34d92fe6d86cc43ca8fecdf44dc30 plugins/AuthzLDAP/lib/Jifty/Plugin/AuthzLDAP/Model/LDAPFilter.pm
 SHA1 dc50e07d76934884116843767a1784571accac4e plugins/AuthzLDAP/share/po/en.po
 SHA1 18be32490b494470824534cccd87b034cd790987 plugins/AuthzLDAP/share/po/fr.po
 SHA1 cd21439e1906eb58e9c576a477a8a31e05340c05 plugins/AuthzLDAP/share/web/templates/error/AccessDenied
 SHA1 289f295702910035ed2b122279ecf8b3b6a6389b plugins/AuthzLDAP/t/00-load.t
+SHA1 90adb765b74e3b0d115b33a4a6da8ed38a6eb179 plugins/DumpDispatcher/Makefile.PL
+SHA1 94f0d477bc64ce6e88e0023cccc228c4f5ed1cf9 plugins/DumpDispatcher/lib/Jifty/Plugin/DumpDispatcher.pm
 SHA1 e8ce16205eccb1b99224ca81d3a3496163a98864 plugins/EditInPlace/Makefile.PL
 SHA1 f2d5b6fb2d7628c2dd7207a8a7fb3dab1ea2f4bf plugins/EditInPlace/debian/changelog
 SHA1 9c6b057a2b9d96a4067a749ee3b3b0158d390cf1 plugins/EditInPlace/debian/compat
@@ -317,7 +390,7 @@
 SHA1 0c2118868ef82ac517eb6d9c3bd93e6eb9bbf83e plugins/EditInPlace/inc/Module/Install/Win32.pm
 SHA1 e827d6d43771032fa3df35c0ad5e5698d0e54cda plugins/EditInPlace/inc/Module/Install/WriteAll.pm
 SHA1 312dfe93d52daa4c72257cf2299aee35f61b0a16 plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace.pm
-SHA1 187cd200affbf8861a91d008273eb9de664a9d60 plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action/FileEditor.pm
+SHA1 5cb6593e89cc253b5f3a99eb8e08366b3b7bd119 plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action/FileEditor.pm
 SHA1 69ff778cc486bfd14a97f7690a7706633dbc2e6b plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Dispatcher.pm
 SHA1 6f363a3b2826ee1fb01921fefebaf99b111a1c31 plugins/EditInPlace/share/web/templates/__jifty/create_file_inline
 SHA1 dc4e60f93e56496f8010ae81888e84e3352e979f plugins/EditInPlace/share/web/templates/__jifty/edit_file
@@ -328,16 +401,342 @@
 SHA1 e84437393b86a21e865df9ea0d0711a75ef4928e plugins/EmailErrors/lib/Jifty/Plugin/EmailErrors/Dispatcher.pm
 SHA1 20fcd16f0baba3e0114bc73d2dca0c9da3a6405c plugins/EmailErrors/lib/Jifty/Plugin/EmailErrors/Notification/EmailError.pm
 SHA1 da39a3ee5e6b4b0d3255bfef95601890afd80709 plugins/EmailErrors/share/web/templates/.file
+SHA1 ebcfb9af339f6dee2bdd2b2d8157dadec865affc plugins/ExtJS/Makefile.PL
+SHA1 1ca711c23637fe2e9f7bb7bf17b20b5863957a63 plugins/ExtJS/lib/Jifty/Plugin/ExtJS.pm
+SHA1 19143ed81fe29776e2279aa3f7fdff436fc0aabe plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Dispatcher.pm
+SHA1 68f6be906ddf65f2ae2221f17ad98ed9558e70de plugins/ExtJS/share/web/static/css/extjs/README.txt
+SHA1 a9e97f3355a1d406d0fc42ceb97fe3fc8737fc78 plugins/ExtJS/share/web/static/css/extjs/basic-dialog.css
+SHA1 25c23bca05a866670b2f336eee9335613e21ebed plugins/ExtJS/share/web/static/css/extjs/box.css
+SHA1 0761657572ec7e7459f7d3a790ab6548b081f1af plugins/ExtJS/share/web/static/css/extjs/button.css
+SHA1 4d5da1cb3722bbed33337fcb3f791cdfcd1e0ed8 plugins/ExtJS/share/web/static/css/extjs/combo.css
+SHA1 881bc6e67800fa39a41c6aa2ffc8813cbec83048 plugins/ExtJS/share/web/static/css/extjs/core.css
+SHA1 e4a52f11ab321155c2be0d04c4bf7f650dd813c0 plugins/ExtJS/share/web/static/css/extjs/date-picker.css
+SHA1 6a8d2c690d4729933d3db45cdd0436fdc97624fa plugins/ExtJS/share/web/static/css/extjs/dd.css
+SHA1 1f788fb3485a38907fb11015bc2805fde256772c plugins/ExtJS/share/web/static/css/extjs/debug.css
+SHA1 7b03666a243e7b1ed236ff3ae838828c949756d9 plugins/ExtJS/share/web/static/css/extjs/ext-all.css
+SHA1 446f2550c5ded1283fcbc5841e27444ca75f383b plugins/ExtJS/share/web/static/css/extjs/form.css
+SHA1 712a28a1854691f6998737a9523d3c59390db9f8 plugins/ExtJS/share/web/static/css/extjs/grid.css
+SHA1 0a2805e890d0bf5d2cd15d226f97e70aec0f5d7d plugins/ExtJS/share/web/static/css/extjs/layout.css
+SHA1 ee4cb6f34e1bf8ac1d649acaed4fecb8c5c03641 plugins/ExtJS/share/web/static/css/extjs/menu.css
+SHA1 7f0233fe0fda1d2d3241f0d0c04bc299b98afadb plugins/ExtJS/share/web/static/css/extjs/qtips.css
+SHA1 21b5726f602652b15c15cd854eb5263614bc1e7f plugins/ExtJS/share/web/static/css/extjs/reset-min.css
+SHA1 ef8cc7c41f2003e9c987e76b007451e1c042123c plugins/ExtJS/share/web/static/css/extjs/resizable.css
+SHA1 6211d9892acb545ef83962eb979c0de5efa8c2d8 plugins/ExtJS/share/web/static/css/extjs/tabs.css
+SHA1 1aeffa3fa12a8e7074aa73a4306796beebe064f5 plugins/ExtJS/share/web/static/css/extjs/toolbar.css
+SHA1 38984a451ef6887f3f74307735b1ef2cbf14736e plugins/ExtJS/share/web/static/css/extjs/tree.css
+SHA1 af7ab3c19612b2b7d1e18347f67f3697de7e801c plugins/ExtJS/share/web/static/css/extjs/ytheme-aero.css
+SHA1 586251d6b3b27d865aec4e8899f1fa7a34cc030d plugins/ExtJS/share/web/static/css/extjs/ytheme-gray.css
+SHA1 28a4d83e3439f6591605c543a44af96b22a62aca plugins/ExtJS/share/web/static/css/extjs/ytheme-vista.css
+SHA1 722f821c05eedd73ceb84c04a496ef2fab0ae6d0 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close-over.gif
+SHA1 298a73ca768795b49481b5c067966cd31b932aa3 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close.gif
+SHA1 2eb77589c44f08ea4613f563715fde0e86c356ba plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-center.gif
+SHA1 878f892fe63f05df71cf1d2d203d087a99816935 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-left.gif
+SHA1 89979519429742ec3a6ae889fcd5005748567cfc plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-right.gif
+SHA1 78508bc449d3f834c4c1a45d88a97de26ba63d03 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/close.gif
+SHA1 7e0be477622fbc3c7e50adb1fd898d293ab349d1 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse-over.gif
+SHA1 70b328ea37e72746b5be2dab02852c2a661890d9 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse.gif
+SHA1 95a5575847d1b826aad606e0e8f4e675be584f0d plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/e-handle.gif
+SHA1 8d032235ea2cd6803f0c28767607a55ab2fda41a plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand-over.gif
+SHA1 40b01d8059d4803cf93a9e15ab526e9bb1e6a136 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand.gif
+SHA1 6f882b664bd421bef833b9b58ff030cd5b13ee31 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/hd-sprite.gif
+SHA1 9fcea223539a9a2e5f128f4f7b0622202b20b7f7 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/s-handle.gif
+SHA1 1a481ec7d6151220bffb616e7bf095c1d63f65e7 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/se-handle.gif
+SHA1 468a6b27c35716cbf688558328652aaeb2600294 plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/w-handle.gif
+SHA1 0b79d2c11d9ef82afd725c337190bf2fc0ecdbed plugins/ExtJS/share/web/static/images/extjs/aero/gradient-bg.gif
+SHA1 5488bbf3ee8a87f3a81e1813841800d162c471f7 plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-blue-split.gif
+SHA1 405cbda624a021dee43f5d967d33df7e2a0c0dec plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-hrow.gif
+SHA1 d27501ba0e05f40637afd3c6f2beeb3200b4ba6e plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-split.gif
+SHA1 c74324b324a276c45b68239b20e033405483db5b plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-vista-hd.gif
+SHA1 d7d593aa0995d1ead5098cc123f4a27dd1a58274 plugins/ExtJS/share/web/static/images/extjs/aero/grid/pspbrwse.jbf
+SHA1 7f94922b69d724d7983c181fd909431fbe6df481 plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort-col-bg.gif
+SHA1 296bb89bfaef25a5189740258b0cd1217daac43b plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_asc.gif
+SHA1 fe064eee5889f5b47179f9820e89a33785dd3226 plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_desc.gif
+SHA1 ff856305c4c510a0c760891689e5be286b518e44 plugins/ExtJS/share/web/static/images/extjs/aero/layout/collapse.gif
+SHA1 2ad5d274c19032d93e370319f32dc42e2e46a363 plugins/ExtJS/share/web/static/images/extjs/aero/layout/expand.gif
+SHA1 ef69813d517535adaf5a814d1c3af75999d035e3 plugins/ExtJS/share/web/static/images/extjs/aero/layout/gradient-bg.gif
+SHA1 12bd112fdbc5cace0d53e77c1284f180bf02eba3 plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-collapse.gif
+SHA1 4ab74cefb173a85a88319cea98947787520545a9 plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-expand.gif
+SHA1 491c85c0a9eeed1699e9eaa4f6762003e661da22 plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-close.gif
+SHA1 c61ebb55f6fd57c07f383abbd63c744dd9dbf9fe plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-bg.gif
+SHA1 293fa9ceefabc2fbbcb841fb0888eab8036a8d1b plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-light-bg.gif
+SHA1 9d61565a5eff943a2e459de54e22ab5c37fcc05d plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close-on.gif
+SHA1 ec442b424b2c4b1253e30f278df22980734e04af plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close.gif
+SHA1 23568c5736706434749b80d47b5eb366654fdba5 plugins/ExtJS/share/web/static/images/extjs/aero/qtip/bg.gif
+SHA1 56d45f8a17f5078a20af9962c992ca4678450765 plugins/ExtJS/share/web/static/images/extjs/aero/s.gif
+SHA1 8fdf6b47fd67f130e5e8629d29cf706f1aea80ea plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle-dark.gif
+SHA1 5e16ea1295ea2d2ac6db43dfc38f0c3f20afed2d plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle.gif
+SHA1 50540363b5af2f9bbd17a3cc3499e39f68352981 plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle-dark.gif
+SHA1 c0ce8ea31045ba8634d200b4ac845b369a6d2623 plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle.gif
+SHA1 16dd0ecc9121959508c1cbf5849ff77c84650ece plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle-dark.gif
+SHA1 abe8f980bc44bc293bffdc3a9dd9c961f0fb9fe9 plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle.gif
+SHA1 50fd1d402c0948846cd7537b5c518103863a9fad plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle-dark.gif
+SHA1 e8342b01f88fa864c59ba7404f0988740133dc84 plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle.gif
+SHA1 88eb063246be44275c540deb747f4c1bdf9f89c7 plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle-dark.gif
+SHA1 20706bdc544acfc752f9f443abad05f6804b065b plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle.gif
+SHA1 255a6d93f557be475f59e7ee05fe242b00eec5cb plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle-dark.gif
+SHA1 e01505e9b5672554830678ca8ac99b026d1a6bf0 plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle.gif
+SHA1 77f193ab1c4cd7831c12f80c07a7a45bc0aece25 plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-left-bg.gif
+SHA1 7a71c1791cefa45ba0b18703a98cb3cd161373cc plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-right-bg.gif
+SHA1 787a1b6e799a3e7ed2e067c037170571d5d19a20 plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-left-bg.gif
+SHA1 92a636351ccf251c23372397b589ba7b1ac7ddc1 plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-right-bg.gif
+SHA1 74a5c6c4fa560b6c3c2f8aca7e813404ab108d0b plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-sprite.gif
+SHA1 2decda868adac2c9b596a97bd6e4bea0cc15c05a plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.gif
+SHA1 4e37a3465f9086bdb499bb5c27bf3805848146d3 plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.png
+SHA1 a83f08b232bc764f759b739236656e144ed99410 plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-btm-bg.gif
+SHA1 a7dfe44a83499dcd5894cc2a74ff5706a15d2c8d plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/bg.gif
+SHA1 c10fd56f2102a281c2f2f980ad4450d61f755ae4 plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/tb-btn-sprite.gif
+SHA1 e83a971cfa2f24db9964681499ffa9ae620a1807 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-arrow.gif
+SHA1 41e800fd5658c58fb9a9e4c52d96e131996ffcaf plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-sprite.gif
+SHA1 048880258d1b16ed111820a8c2a5d603f6f0396b plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/close.gif
+SHA1 ef12ee75d08d364e238c9603ad5bbf5ab753cd46 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/collapse.gif
+SHA1 c88166931fca03dc33d569bf405f924ae40cf1a0 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/e-handle.gif
+SHA1 0695b5346e21097e981c6ebce3bf5c215cd1e7c2 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/expand.gif
+SHA1 6bb19dee3e503856d537c750c76db8fc874fe142 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/hd-sprite.gif
+SHA1 aa63488c369f42749ed5a06502b293dfaa75ba0e plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress.gif
+SHA1 6f5a1c1a665faae326e514c598de62e6f9fb0090 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress2.gif
+SHA1 82ff322025b7ad4cb8896c58d9b496a92439bd70 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/s-handle.gif
+SHA1 0680315f0850c26cd4402f59a5082e9d2a6673f7 plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/se-handle.gif
+SHA1 f2357c7511bae47f17a02586769afe78cb85522e plugins/ExtJS/share/web/static/images/extjs/default/box/corners-blue.gif
+SHA1 8c4a83d6f0f7b75fb7c8a30821e871d246ba8568 plugins/ExtJS/share/web/static/images/extjs/default/box/corners.gif
+SHA1 4f5bdda24a3e4274b92ff391e5341f7ee328a7d7 plugins/ExtJS/share/web/static/images/extjs/default/box/l-blue.gif
+SHA1 03fe8f5a132948941eaadf3791001c39e03df9e8 plugins/ExtJS/share/web/static/images/extjs/default/box/l.gif
+SHA1 8f0626925774c7861cd55ed76dd5e69594977bbe plugins/ExtJS/share/web/static/images/extjs/default/box/r-blue.gif
+SHA1 422e77206f02745354426d179701cac2d79eb33c plugins/ExtJS/share/web/static/images/extjs/default/box/r.gif
+SHA1 2bb7d59c94e3ec6d3cac83f57206fdfbe9fee7a5 plugins/ExtJS/share/web/static/images/extjs/default/box/tb-blue.gif
+SHA1 1664b2093acfb8b1a840646bae51399bada33c5d plugins/ExtJS/share/web/static/images/extjs/default/box/tb.gif
+SHA1 0fa08cc1fe9e2c7932ab6b41ce8dd16815852af3 plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-add.gif
+SHA1 7202cf00a47a812cc139dcd9d119e00227a9242b plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-no.gif
+SHA1 cc59e44f48eada4150b5c657c928dde8eb624350 plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-yes.gif
+SHA1 479a5a54d8a1daf3f003fe7e96fcf81d6086914c plugins/ExtJS/share/web/static/images/extjs/default/form/date-trigger.gif
+SHA1 0b2ccb38837849fe75ce7cee23843d92522b0956 plugins/ExtJS/share/web/static/images/extjs/default/form/error-tip-corners.gif
+SHA1 075c5e4f814e22e48f563d9c5ed46a84863181a4 plugins/ExtJS/share/web/static/images/extjs/default/form/exclamation.gif
+SHA1 14ce153d393b3c489f8a4e6b9a9383e7d8f4c911 plugins/ExtJS/share/web/static/images/extjs/default/form/text-bg.gif
+SHA1 0c298c9fc7211b3d921120cd7da128cb4765a778 plugins/ExtJS/share/web/static/images/extjs/default/form/trigger.gif
+SHA1 0b79d2c11d9ef82afd725c337190bf2fc0ecdbed plugins/ExtJS/share/web/static/images/extjs/default/gradient-bg.gif
+SHA1 dacbac8995f32560d3c8c4b7bc33ef3d0256ae3f plugins/ExtJS/share/web/static/images/extjs/default/grid/Thumbs.db
+SHA1 ba9a84e01a9e6e08c2ec534c0d0befcd07e4a7e5 plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-left-white.gif
+SHA1 c0381f6ae0afef110bbaadd51aa5a39200b8b3c7 plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-right-white.gif
+SHA1 db4d02b2fac8bc3baa82432c0106be2e40e27419 plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-bottom.gif
+SHA1 60deb1f7ca78aadcb8ed2a825e6b6ba07684a33d plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-top.gif
+SHA1 ccf202fdeb74fbc829b4309198b473c5f94e437d plugins/ExtJS/share/web/static/images/extjs/default/grid/dirty.gif
+SHA1 cda9d3b74238adb9f1412946297e90eb0b2484f6 plugins/ExtJS/share/web/static/images/extjs/default/grid/done.gif
+SHA1 83767bdb2130a4b3e3371450fa138a4a6ae3f9cc plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-no.gif
+SHA1 c98b6f3b8fb7aad0914fb502bd7a900ce46cb4fb plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-yes.gif
+SHA1 6f3172242ebd53cb8e0ad2e7a42fbae8f063e27a plugins/ExtJS/share/web/static/images/extjs/default/grid/footer-bg.gif
+SHA1 a62484058357624c7c15bc4c63a9e5beb4f9a285 plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-hd.gif
+SHA1 5488bbf3ee8a87f3a81e1813841800d162c471f7 plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-split.gif
+SHA1 4604e3ed860a9ec8e4a3ddc72b7a5751506da57d plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-hrow.gif
+SHA1 e3d3509dd9120fa866a718f57ec681f5018dad4a plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-loading.gif
+SHA1 aa24a1f36b4fe7069ae97bd9c42db5f3310dd7f6 plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-split.gif
+SHA1 c74324b324a276c45b68239b20e033405483db5b plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-vista-hd.gif
+SHA1 a797e5a37285e8a5df5fc155bd86b1bafc2f713a plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-asc.gif
+SHA1 2851aa4e87a0b95d5d7add1b557ba2f625fa0733 plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-desc.gif
+SHA1 1d2ca1c02de35c474a6c12f13ab55c5e1bd076ca plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.gif
+SHA1 f9958b09b1b8ed0e2d11352f8e047d73e2b58223 plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.png
+SHA1 c0c0102a864e3fc0c5d4af336f6b011f90f05957 plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.gif
+SHA1 a762d375660eb903de307efe0ee2244cfcbdf45e plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.png
+SHA1 b0c2cc0034a3fda3697b37f0e491b9a8deee54dd plugins/ExtJS/share/web/static/images/extjs/default/grid/invalid_line.gif
+SHA1 942d8fe092c1c473af19906751c2bee5322a9b55 plugins/ExtJS/share/web/static/images/extjs/default/grid/loading.gif
+SHA1 012efd8f96ee4c40499dd2bfca8304df7467216a plugins/ExtJS/share/web/static/images/extjs/default/grid/mso-hd.gif
+SHA1 459ef504a2e662cd46873806abebed988db6b75b plugins/ExtJS/share/web/static/images/extjs/default/grid/nowait.gif
+SHA1 3b776004161d64fd956b49cf83ec235ee458271d plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first-disabled.gif
+SHA1 0806bc00d5eb3948773c20f9809c66f78bb8352b plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first.gif
+SHA1 9b1611918e00eeb2f4ac2d945dfad31109806c7e plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last-disabled.gif
+SHA1 a2a8aef85c948f240b2af7f22ccd844d03ba6765 plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last.gif
+SHA1 7bbb12b24e55cb4974def90dee5f85833b33c963 plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next-disabled.gif
+SHA1 65b77a90ecdf2e922d02a34e9796da07daae6648 plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next.gif
+SHA1 e5609036ae330bc1ec625414f4c4b338624d033e plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev-disabled.gif
+SHA1 24460a1dc0b3cd69e8093994596a75806236c5a4 plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev.gif
+SHA1 7746b6f24308b76a08dff00ff9cb66ad3776d90a plugins/ExtJS/share/web/static/images/extjs/default/grid/pick-button.gif
+SHA1 4eb78deade757858f634c683666ec8cd03c1c621 plugins/ExtJS/share/web/static/images/extjs/default/grid/refresh.gif
+SHA1 f004a14bfd0174705db8c906cc07d1526333b659 plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_asc.gif
+SHA1 8320c00b5938b0e35d7d93d7b5777ce5e28870bb plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_desc.gif
+SHA1 6d20137a80a8e1f9d7fe6d5c41fbc06ac98cc914 plugins/ExtJS/share/web/static/images/extjs/default/grid/wait.gif
+SHA1 e3c03133c33fac26e92896504f534120089b41df plugins/ExtJS/share/web/static/images/extjs/default/layout/collapse.gif
+SHA1 5486e515684b5b3a839c765e770a25583ffc4e16 plugins/ExtJS/share/web/static/images/extjs/default/layout/expand.gif
+SHA1 0b79d2c11d9ef82afd725c337190bf2fc0ecdbed plugins/ExtJS/share/web/static/images/extjs/default/layout/gradient-bg.gif
+SHA1 6d2ec8a24c1d559eb27c30e8914b7970344a8c34 plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-collapse.gif
+SHA1 9aea9de63edcd8fada6de9a1121331d8bbc75233 plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-expand.gif
+SHA1 691c4b891370706632e8e72dbe8566d6556f31a6 plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-close.gif
+SHA1 935adb5889ea0082be8f8cd5122b930c957f7c2b plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-bg.gif
+SHA1 2b402ce9faaaec89a4f21f24f564bbb3a70daee3 plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-light-bg.gif
+SHA1 200ea96a78b8e54f8c42ed5e4dcbc398ffa8a8b5 plugins/ExtJS/share/web/static/images/extjs/default/layout/stick.gif
+SHA1 6a629898a4a47d61baec1d67ac335ba706fb40e8 plugins/ExtJS/share/web/static/images/extjs/default/layout/stuck.gif
+SHA1 673ffac1a25a19b05c37ce4776e38ed03ee9a97e plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close-on.gif
+SHA1 8b502fb30e8b3be3866789533165a1dfd671cfef plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close.gif
+SHA1 177624cbe183b44ff0ddfb907cc9d8bc5826491e plugins/ExtJS/share/web/static/images/extjs/default/menu/checked.gif
+SHA1 24522e5bca535a24e9623db71abb5c078834c62f plugins/ExtJS/share/web/static/images/extjs/default/menu/group-checked.gif
+SHA1 ab855c96778a3212858089baacda447759a95292 plugins/ExtJS/share/web/static/images/extjs/default/menu/menu-parent.gif
+SHA1 dd2ce6ac48da733fe7f992cf3845e499516c9a67 plugins/ExtJS/share/web/static/images/extjs/default/menu/menu.gif
+SHA1 d826c591ac66a8e4fccd7d46c9adc7ef89be00b0 plugins/ExtJS/share/web/static/images/extjs/default/menu/unchecked.gif
+SHA1 b2f4d43f704dfe5f157570075293ba719cb9343c plugins/ExtJS/share/web/static/images/extjs/default/qtip/bg.gif
+SHA1 c0b8a69f763736957caf3132410bfe1461c4e953 plugins/ExtJS/share/web/static/images/extjs/default/qtip/close.gif
+SHA1 5ed1849f477fb1ce1cc7878de73f0a038f53eee9 plugins/ExtJS/share/web/static/images/extjs/default/qtip/tip-sprite.gif
+SHA1 56d45f8a17f5078a20af9962c992ca4678450765 plugins/ExtJS/share/web/static/images/extjs/default/s.gif
+SHA1 5c89b09a00ddcd17f3d7a9fe1a880aa04cebeedc plugins/ExtJS/share/web/static/images/extjs/default/shadow-lr.png
+SHA1 9f8e529ab913563a27dd3389fec1dfd072fe0433 plugins/ExtJS/share/web/static/images/extjs/default/shadow.png
+SHA1 6481371769cf6291b4e78e49b16603e3105c93c4 plugins/ExtJS/share/web/static/images/extjs/default/shared/calendar.gif
+SHA1 44d4718df69f48845c61abf1c1450958cf0479f9 plugins/ExtJS/share/web/static/images/extjs/default/shared/left-btn.gif
+SHA1 34fbf9fef3ca8c1d1fd183eb832b5a1bf497bfd5 plugins/ExtJS/share/web/static/images/extjs/default/shared/right-btn.gif
+SHA1 d9067923247942d58c93dbae33dcda4a0c814159 plugins/ExtJS/share/web/static/images/extjs/default/shared/warning.gif
+SHA1 ca4502333928e62174c89fd4121b578dbcec9756 plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle-dark.gif
+SHA1 ba378b831eecd704c531a4e6f27289e15e25bd53 plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle.gif
+SHA1 aeb5fbaa988900672baf4d38325197212b2fe168 plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle-dark.gif
+SHA1 074eda992155b4411d4d7d1dbde08d678d028248 plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle.gif
+SHA1 29cf4ac5755c1dff0dafbe4bcba08002828a4959 plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle-dark.gif
+SHA1 3d4a99bad6353f7900195142b17f121727e0b79a plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle.gif
+SHA1 a4dc8f677a6abebd7c0c4db0953d062a7bfaf189 plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle-dark.gif
+SHA1 4a1da81042b989e387204cd24e703e8485c01374 plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle.gif
+SHA1 768e9f6bac34d4af6550d8234ceb37bb4d15f36d plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle-dark.gif
+SHA1 23631eb77516b9d80138a4d1beb6776ba7294c07 plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle.gif
+SHA1 c0ca58c8df8eddd7a5372bfbd09f484cde78e4b8 plugins/ExtJS/share/web/static/images/extjs/default/sizer/square.gif
+SHA1 dfed4d77852f5f6dd2f3c6bba23bb40b2302396c plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle-dark.gif
+SHA1 74d49e57135117e1681798de9ea49640c0004c31 plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle.gif
+SHA1 d3d040deb0a1e08fe553dc36a6dc75eecc117102 plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-left-bg.gif
+SHA1 b0c76b3d266a5c809be7516ae4457748f667276c plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-right-bg.gif
+SHA1 c4cea97deaa0475222e4ea9125ca7bc87b22c3c5 plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-left-bg.gif
+SHA1 090bbea1c4a0a049500069aa9314e9796f038b4c plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-right-bg.gif
+SHA1 fb49e69ce6d9c65840933917e7e957b3e0a52f9b plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-sprite.gif
+SHA1 160e46c26460402904800c4857848711d643429a plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow-light.gif
+SHA1 7ef67fd2481bb3fbee9667d21dc74441871544e3 plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow.gif
+SHA1 e2540d51be724fa077f4fabd9416aebb27926868 plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-over-bg.gif
+SHA1 b58894f8544eb7db29353fd7d5c6a53efca2a0f0 plugins/ExtJS/share/web/static/images/extjs/default/toolbar/gray-bg.gif
+SHA1 95917df9e2d62bb21d7d290576bfdef8fc177d90 plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-bg.gif
+SHA1 a019fbf74a4cbe3149e0c7b264c05d65178058f4 plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-btn-sprite.gif
+SHA1 0fa08cc1fe9e2c7932ab6b41ce8dd16815852af3 plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-add.gif
+SHA1 5d3d4f3b1d11f277b9fb36b0962d881a2a6dc63b plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-between.gif
+SHA1 fb27f031501ff6cc8d5d12fbd9df526045c87fc7 plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-no.gif
+SHA1 26989c5a898467b5f7187e2734eb33050864f441 plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-over.gif
+SHA1 0a2b0bc935bf653f6b7010eced1e2ca8dbecc799 plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-under.gif
+SHA1 cc59e44f48eada4150b5c657c928dde8eb624350 plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-yes.gif
+SHA1 29c03b23895d652aefe684971367024068e3c942 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus-nl.gif
+SHA1 6a026a1b1457081f5958c9b2c237a6b0638a93f6 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus.gif
+SHA1 82ef2e378481e16a4008bf9f9802817a58acef76 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus-nl.gif
+SHA1 60f1a73ba9d952f5c4823e3206792b14c380b00d plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus.gif
+SHA1 335f08289b716d76e423f4f3eeee2503f37ec9cb plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end.gif
+SHA1 c990d8958f8082d701b4250cec7b70aa74265a24 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-line.gif
+SHA1 29c03b23895d652aefe684971367024068e3c942 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus-nl.gif
+SHA1 34498a6c896f949410b56f58064b0751546b0b3f plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus.gif
+SHA1 82ef2e378481e16a4008bf9f9802817a58acef76 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus-nl.gif
+SHA1 7f9332b60e1d7e68b4db26d8d7ce5a6568350794 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus.gif
+SHA1 ce9c66f9c893e72a78964a35be107602c31022d0 plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow.gif
+SHA1 131dca28bedc85d776f58800cf15f5811e3df5cf plugins/ExtJS/share/web/static/images/extjs/default/tree/folder-open.gif
+SHA1 1b3a928787bfa0cba7fa6520f07f978483ba90ea plugins/ExtJS/share/web/static/images/extjs/default/tree/folder.gif
+SHA1 587efd117c281e8a039b9c28c5b8311acb442047 plugins/ExtJS/share/web/static/images/extjs/default/tree/leaf.gif
+SHA1 942d8fe092c1c473af19906751c2bee5322a9b55 plugins/ExtJS/share/web/static/images/extjs/default/tree/loading.gif
+SHA1 56d45f8a17f5078a20af9962c992ca4678450765 plugins/ExtJS/share/web/static/images/extjs/default/tree/s.gif
+SHA1 6095b6b0d99eeb10c9384e9b5e93b15af869251a plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/close.gif
+SHA1 f8a0262ffc92e1e2cb447958ac07fa3509080d0f plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/collapse.gif
+SHA1 0bd62da4853ed04876d69c0be44beab7d4ec90dc plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/dlg-bg.gif
+SHA1 95a5575847d1b826aad606e0e8f4e675be584f0d plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/e-handle.gif
+SHA1 30a8e91dca9e5ef6978b888159921f5c8e823b96 plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/expand.gif
+SHA1 7e3cd770de47c9457ddc789c6b0b2e194d1eb422 plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/hd-sprite.gif
+SHA1 9fcea223539a9a2e5f128f4f7b0622202b20b7f7 plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/s-handle.gif
+SHA1 cad637db3d6c84e65e2edb9976ef0d35fc5f9a6a plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/se-handle.gif
+SHA1 0b79d2c11d9ef82afd725c337190bf2fc0ecdbed plugins/ExtJS/share/web/static/images/extjs/gray/gradient-bg.gif
+SHA1 38c24fefd042141bbd158d4df952c6f6a1e01cab plugins/ExtJS/share/web/static/images/extjs/gray/grid/grid-hrow.gif
+SHA1 4acb5c1d3514b03708936207c41b4edac2470244 plugins/ExtJS/share/web/static/images/extjs/gray/layout/collapse.gif
+SHA1 6f4b5b7723d2fcf49d1338589d43c4bb149450dd plugins/ExtJS/share/web/static/images/extjs/gray/layout/expand.gif
+SHA1 ef69813d517535adaf5a814d1c3af75999d035e3 plugins/ExtJS/share/web/static/images/extjs/gray/layout/gradient-bg.gif
+SHA1 aaa1eb99db602aae777a47861ec4c3139c59e5a7 plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-collapse.gif
+SHA1 d52a8d75563a083776b5a228a746c92c0d939cc0 plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-expand.gif
+SHA1 491c85c0a9eeed1699e9eaa4f6762003e661da22 plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-close.gif
+SHA1 935adb5889ea0082be8f8cd5122b930c957f7c2b plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-bg.gif
+SHA1 4323dd3c33cb590efde91df1a69c21e73e2a6946 plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-light-bg.gif
+SHA1 640f0efc54b4bb893d093bccd936cdc26471367e plugins/ExtJS/share/web/static/images/extjs/gray/layout/stick.gif
+SHA1 9d61565a5eff943a2e459de54e22ab5c37fcc05d plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close-on.gif
+SHA1 8b502fb30e8b3be3866789533165a1dfd671cfef plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close.gif
+SHA1 177624cbe183b44ff0ddfb907cc9d8bc5826491e plugins/ExtJS/share/web/static/images/extjs/gray/menu/checked.gif
+SHA1 24522e5bca535a24e9623db71abb5c078834c62f plugins/ExtJS/share/web/static/images/extjs/gray/menu/group-checked.gif
+SHA1 116cfb20815432217f1e9f6e4b72a5f37c342061 plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu-parent.gif
+SHA1 0f804d96fafe4fa0c3f93355e7c8b1be3c3efbe0 plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu.gif
+SHA1 d826c591ac66a8e4fccd7d46c9adc7ef89be00b0 plugins/ExtJS/share/web/static/images/extjs/gray/menu/unchecked.gif
+SHA1 23568c5736706434749b80d47b5eb366654fdba5 plugins/ExtJS/share/web/static/images/extjs/gray/qtip/bg.gif
+SHA1 83b276fdede6e24ec5bc7fb3246a2f97fcbcc8ce plugins/ExtJS/share/web/static/images/extjs/gray/qtip/tip-sprite.gif
+SHA1 56d45f8a17f5078a20af9962c992ca4678450765 plugins/ExtJS/share/web/static/images/extjs/gray/s.gif
+SHA1 8fdf6b47fd67f130e5e8629d29cf706f1aea80ea plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle-dark.gif
+SHA1 5e16ea1295ea2d2ac6db43dfc38f0c3f20afed2d plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle.gif
+SHA1 50540363b5af2f9bbd17a3cc3499e39f68352981 plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle-dark.gif
+SHA1 c0ce8ea31045ba8634d200b4ac845b369a6d2623 plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle.gif
+SHA1 16dd0ecc9121959508c1cbf5849ff77c84650ece plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle-dark.gif
+SHA1 abe8f980bc44bc293bffdc3a9dd9c961f0fb9fe9 plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle.gif
+SHA1 50fd1d402c0948846cd7537b5c518103863a9fad plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle-dark.gif
+SHA1 e8342b01f88fa864c59ba7404f0988740133dc84 plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle.gif
+SHA1 88eb063246be44275c540deb747f4c1bdf9f89c7 plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle-dark.gif
+SHA1 20706bdc544acfc752f9f443abad05f6804b065b plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle.gif
+SHA1 255a6d93f557be475f59e7ee05fe242b00eec5cb plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle-dark.gif
+SHA1 e01505e9b5672554830678ca8ac99b026d1a6bf0 plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle.gif
+SHA1 71ed43edaa10f1de36f66ba1ccab598eb1367bdd plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-left-bg.gif
+SHA1 7ac9f4da122eeb3ed839f9011b6a7f8ca6b3b63b plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-right-bg.gif
+SHA1 9a8887a20650d46729a4367d65d1f151a24d9059 plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-left-bg.gif
+SHA1 154e5236085e0742b62b1314aa4798d63662ad07 plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-right-bg.gif
+SHA1 6ffd462ff5ffec4305484a40c45d05b06a3d4c1a plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-sprite.gif
+SHA1 b58894f8544eb7db29353fd7d5c6a53efca2a0f0 plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/gray-bg.gif
+SHA1 39ff4711989df83ae826188e2c8f61864069edf5 plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/tb-btn-sprite.gif
+SHA1 ff82b2653be183c6b138d9e360e2e32306d8e3fb plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-center.gif
+SHA1 50bc7d2ece8c990b7939688ab0c691331e30541c plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-left.gif
+SHA1 b999604b6269a42bae0ba7875503d514f5a200b2 plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-right.gif
+SHA1 78508bc449d3f834c4c1a45d88a97de26ba63d03 plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/close.gif
+SHA1 8abbb2dd5c6d73de107f8b28cfc870d6e41ae90c plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/collapse.gif
+SHA1 0bd62da4853ed04876d69c0be44beab7d4ec90dc plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/dlg-bg.gif
+SHA1 95a5575847d1b826aad606e0e8f4e675be584f0d plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/e-handle.gif
+SHA1 fee3a806e21d5ba09082ea07972768ecbd2c14d5 plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/expand.gif
+SHA1 0b7eb14d7e6bd0a5caeca065eed4d03324ba8363 plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/hd-sprite.gif
+SHA1 9fcea223539a9a2e5f128f4f7b0622202b20b7f7 plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/s-handle.gif
+SHA1 cad637db3d6c84e65e2edb9976ef0d35fc5f9a6a plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/se-handle.gif
+SHA1 468a6b27c35716cbf688558328652aaeb2600294 plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/w-handle.gif
+SHA1 0b79d2c11d9ef82afd725c337190bf2fc0ecdbed plugins/ExtJS/share/web/static/images/extjs/vista/gradient-bg.gif
+SHA1 aa24a1f36b4fe7069ae97bd9c42db5f3310dd7f6 plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-split.gif
+SHA1 c74324b324a276c45b68239b20e033405483db5b plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-vista-hd.gif
+SHA1 ff856305c4c510a0c760891689e5be286b518e44 plugins/ExtJS/share/web/static/images/extjs/vista/layout/collapse.gif
+SHA1 2ad5d274c19032d93e370319f32dc42e2e46a363 plugins/ExtJS/share/web/static/images/extjs/vista/layout/expand.gif
+SHA1 ef69813d517535adaf5a814d1c3af75999d035e3 plugins/ExtJS/share/web/static/images/extjs/vista/layout/gradient-bg.gif
+SHA1 12bd112fdbc5cace0d53e77c1284f180bf02eba3 plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-collapse.gif
+SHA1 4ab74cefb173a85a88319cea98947787520545a9 plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-expand.gif
+SHA1 491c85c0a9eeed1699e9eaa4f6762003e661da22 plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-close.gif
+SHA1 53a4ce82ec874b935255b10e9d0e6bc6de11d27a plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-bg.gif
+SHA1 2687d6b96b953056de987c0d0a152704de145def plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-light-bg.gif
+SHA1 f153a582cff1bbc2cd401799ca8c6464a7f6a4a2 plugins/ExtJS/share/web/static/images/extjs/vista/layout/stick.gif
+SHA1 9d61565a5eff943a2e459de54e22ab5c37fcc05d plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close-on.gif
+SHA1 ec442b424b2c4b1253e30f278df22980734e04af plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close.gif
+SHA1 23568c5736706434749b80d47b5eb366654fdba5 plugins/ExtJS/share/web/static/images/extjs/vista/qtip/bg.gif
+SHA1 f40799ea96594237934917636548dbd9ff9b4f36 plugins/ExtJS/share/web/static/images/extjs/vista/qtip/tip-sprite.gif
+SHA1 56d45f8a17f5078a20af9962c992ca4678450765 plugins/ExtJS/share/web/static/images/extjs/vista/s.gif
+SHA1 8fdf6b47fd67f130e5e8629d29cf706f1aea80ea plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle-dark.gif
+SHA1 5e16ea1295ea2d2ac6db43dfc38f0c3f20afed2d plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle.gif
+SHA1 50540363b5af2f9bbd17a3cc3499e39f68352981 plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle-dark.gif
+SHA1 c0ce8ea31045ba8634d200b4ac845b369a6d2623 plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle.gif
+SHA1 16dd0ecc9121959508c1cbf5849ff77c84650ece plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle-dark.gif
+SHA1 abe8f980bc44bc293bffdc3a9dd9c961f0fb9fe9 plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle.gif
+SHA1 50fd1d402c0948846cd7537b5c518103863a9fad plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle-dark.gif
+SHA1 e8342b01f88fa864c59ba7404f0988740133dc84 plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle.gif
+SHA1 88eb063246be44275c540deb747f4c1bdf9f89c7 plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle-dark.gif
+SHA1 20706bdc544acfc752f9f443abad05f6804b065b plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle.gif
+SHA1 255a6d93f557be475f59e7ee05fe242b00eec5cb plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle-dark.gif
+SHA1 e01505e9b5672554830678ca8ac99b026d1a6bf0 plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle.gif
+SHA1 31113cd3e4fed3752deda2fe43885385c0d8b778 plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-left-bg.gif
+SHA1 7ec7eb67346e284eb49f081a46c3c4de7c56d520 plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-right-bg.gif
+SHA1 925666fac553b59975c238be26991be98a4a92a8 plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-left-bg.gif
+SHA1 92492dfd42db139aa6ac6bb287dcbd7067e64a34 plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-right-bg.gif
+SHA1 993ece72ab69108dc54fa30548e9729ddd29ca36 plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-sprite.gif
+SHA1 7dd1f119b402d87f1cb6c7fcac09165cc94590cd plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/gray-bg.gif
+SHA1 a22aa021b83471d41cb8f26d33574a7f610d6afd plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/tb-btn-sprite.gif
+SHA1 ae3242c7e7a096f9341ddcf18bd19f4565f82308 plugins/ExtJS/share/web/static/js/extjs/adapter/jquery/ext-jquery-adapter.js
+SHA1 2acec15f4f0c74cacebddae150e8018f10ee6f86 plugins/ExtJS/share/web/static/js/extjs/adapter/prototype/ext-prototype-adapter.js
+SHA1 0e7c77ed98646e13d684e9f4cb8ca8b74fc782a9 plugins/ExtJS/share/web/static/js/extjs/adapter/yui/ext-yui-adapter.js
+SHA1 4d5796abb09cb659035954de0ad0e029f6359eb9 plugins/ExtJS/share/web/static/js/extjs/adapter/yui/yui-utilities.js
+SHA1 00c72717f30c8bf1a4adb52a635209aa76dd45c3 plugins/ExtJS/share/web/static/js/extjs/ext-all.js
+SHA1 4cfbc394ede98c19b24aaef037a37386e3215313 plugins/ExtJS/share/web/static/js/extjs/ext-config.js
 SHA1 6d36892393c5848ca54991272c03460b330734d2 plugins/LetMe/Makefile.PL
 SHA1 88f5ed45b2c506fcab80f178cf4cedd23a62f365 plugins/LetMe/lib/Jifty/Plugin/LetMe.pm
 SHA1 aae4870db361c1076fd151ddd0cf2fd3f02f4813 plugins/LetMe/lib/Jifty/Plugin/LetMe/Dispatcher.pm
 SHA1 5ece7af558c3a7bc83f535e948b7a6b24372daec plugins/Login/MANIFEST
 SHA1 4439300be4c8a1b99726658ceed25674216a079e plugins/Login/META.yml
 SHA1 5d7bbe469fc6a8e0c5f303539c1d235f7c4f50a2 plugins/Login/Makefile.PL
-SHA1 4c552f502b762c8e1a12848423a36ddff99bd38b plugins/Login/debian/changelog
+SHA1 1951523a33e3f0b137db99e76c64c755efcf99d5 plugins/Login/debian/changelog
 SHA1 9c6b057a2b9d96a4067a749ee3b3b0158d390cf1 plugins/Login/debian/compat
 SHA1 90e2e662014841fff93a7e346908f66178dfcc07 plugins/Login/debian/control
-SHA1 df2b684174a5e8bdf6d14b985020057702b4c884 plugins/Login/debian/rules
+SHA1 68dfa9d87a39ca9c6480d8a93e7efb18565b4db3 plugins/Login/debian/rules
 SHA1 017bedfcba1e0c72b36301e6ef21b8712b84d175 plugins/Login/inc/Module/Install.pm
 SHA1 b1a70869c098ba602151631386fc510b5bfd3511 plugins/Login/inc/Module/Install/Base.pm
 SHA1 dd7313db23119d49ae78593bfa576554fb5b0fd8 plugins/Login/inc/Module/Install/Can.pm
@@ -356,10 +755,10 @@
 SHA1 122c7769c6ba202aa4e791f9f34972e58fc1fcd2 plugins/Login/lib/Jifty/Plugin/Login/Action/ResetLostPassword.pm
 SHA1 c2438302917e04b15f940d12452a3d07328ba95d plugins/Login/lib/Jifty/Plugin/Login/Action/SendAccountConfirmation.pm
 SHA1 e238cc4ec479aefb8864ca99984cdea4c76141cf plugins/Login/lib/Jifty/Plugin/Login/Action/SendPasswordReminder.pm
-SHA1 6a41bfe4d8c024874b16f4c8f01d5d16fb77fcd3 plugins/Login/lib/Jifty/Plugin/Login/Action/Signup.pm
+SHA1 9c668df7d6e4453fe5815548aa977e3c2803f21a plugins/Login/lib/Jifty/Plugin/Login/Action/Signup.pm
 SHA1 81875f6ab2d807bfe4671af084b4f238d383464c plugins/Login/lib/Jifty/Plugin/Login/CurrentUser.pm
 SHA1 525f9e063afd64961982b513c5eab0a85909c917 plugins/Login/lib/Jifty/Plugin/Login/Dispatcher.pm
-SHA1 26715ae2299b714b2eeaad1b0d9d709623c2b05d plugins/Login/lib/Jifty/Plugin/Login/Model/User.pm
+SHA1 5f90d761bd912c6baabc81174c2f459fba7a21b3 plugins/Login/lib/Jifty/Plugin/Login/Model/User.pm
 SHA1 3a8233f78d474c2671121f87c7e20bc01ba3090a plugins/Login/lib/Jifty/Plugin/Login/Notification/ConfirmAddress.pm
 SHA1 dd2d89075e1d29eb0e20cfc43fba7db98ef02529 plugins/Login/lib/Jifty/Plugin/Login/Notification/ConfirmLostPassword.pm
 SHA1 c67dcd72acc2f4e5b43863c7480697cc711b5e57 plugins/Login/share/po/en.po
@@ -382,33 +781,63 @@
 SHA1 62229286e03ec35c922c8a7f9f3bb68412a78a55 share/dtd/xhtml-special.ent
 SHA1 e7749f99989ec8a9608f6cfbd41a5e5dddc18aec share/dtd/xhtml-symbol.ent
 SHA1 b4a6d708f6b55a48526e9483c718f2ed820df75c share/dtd/xhtml1-strict.dtd
-SHA1 ddc3a6849e3db2ff2c5e1113a36d6e9869718dc4 share/po/en.po
-SHA1 a2f3d82acc9d343569eb0bc53a1517650c446189 share/po/fr.po
-SHA1 44b99ffe0fd8b2410b3ea5c988ebc61f07d30a38 share/po/ja.po
-SHA1 434c54b1132635916b8f6c70227685661593615d share/po/zh_cn.po
-SHA1 55bf7ecd5ef87fe38e5e3c6d6a0df3b7d8041994 share/po/zh_tw.po
+SHA1 5cfcf2d84b5548b2990efa52e51d3f15a47816b4 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/_elements/nav
+SHA1 6a096f8d324464e6ad6407442faf7b2af0ecdc7e share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/action/dhandler
+SHA1 1b55e3945405d09df59f0a40182f06f8f59a2e97 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/autohandler
+SHA1 51eb5ec4ebe6ad25eac8461c132193ded8ca2640 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/fragments/list/header
+SHA1 80a5f7d081589dba73766f86a79145e997500655 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/fragments/list/list
+SHA1 a73b777585f562210eccba19f007e2ac89b428c4 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/fragments/list/new_item
+SHA1 ed176f653007f8a08e88355bfd68e1b0fc645723 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/fragments/list/search
+SHA1 a118ac016c645629ed720d9626b36266089eee58 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/fragments/list/update
+SHA1 9d339e7acebf3e929b15c1d8b4642ecbddf7f4b6 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/fragments/list/view
+SHA1 559940ee5c2e5b56f3a438f377ea110018e20b18 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/index.html
+SHA1 99ce3e69e2201664a1363ca2535dcc51a64a1f92 share/plugins/Jifty/Plugin/AdminUI/web/templates/__jifty/admin/model/dhandler
+SHA1 7efa4f24d875a19035963c3955f2fc4e613b8cfe share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/autohandler
+SHA1 608c393b35a8884b4d32a4c855bbcc73478dc849 share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/content.html
+SHA1 58a4059cc383f792108986d2386a5e7edc81363f share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/index.html
+SHA1 37555dd5c3acfbaecfc28416e0fa21b0aa6e1d77 share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/toc.html
+SHA1 0da91e5da11aa851363d08a8f9aeade85f72aeb7 share/po/en.po
+SHA1 63a333ff328933df4082e868ba9115b3c0fa24bd share/po/fr.po
+SHA1 88408a7350d0599fd4e7cd7f709fd918b55b6b27 share/po/ja.po
+SHA1 94151e35cbd50a82e09f33718dad3f15fdb0416f share/po/zh_cn.po
+SHA1 623dbb738a8db1e79de6127fc3af2c918d2c93e6 share/po/zh_tw.po
 SHA1 da39a3ee5e6b4b0d3255bfef95601890afd80709 share/web/static/css/app-base.css
 SHA1 da39a3ee5e6b4b0d3255bfef95601890afd80709 share/web/static/css/app.css
 SHA1 c566d7ab5005e82dcf2f90809ae757e07d338138 share/web/static/css/autocomplete.css
 SHA1 5f569fc23eb815ee6f6d086aa6df87f6c38952d3 share/web/static/css/autohandler
-SHA1 c8f7207fab0b74a53a2a798bcedd2f9d94ecc32e share/web/static/css/base.css
+SHA1 98bd4a5fc5cdcf84794d85da8e6a91f13df875cc share/web/static/css/base.css
 SHA1 669f07ab36d148383013733d8230d49e7e7b25ec share/web/static/css/calendar.css
 SHA1 bf48b6bda86f359b95b29a7c3451a3c1b5721385 share/web/static/css/combobox.css
 SHA1 6b4d4cbc063731dabe50356a3560eae6a9f25aef share/web/static/css/context-menus.css
-SHA1 9da37a3dea2259252e33e0cd72198baa04d17530 share/web/static/css/forms.css
+SHA1 4cb352032878df021a9f42e5e6288a00beb259f6 share/web/static/css/forms.css
 SHA1 52ddd83ee7c511d78537454a097f0264a7db3c1c share/web/static/css/halos.css
 SHA1 c7eede0c22f68e4417748bb0903b48195648f4c0 share/web/static/css/keybindings.css
-SHA1 91cd2873a5521bbc172389d8af2c29f33578fcc9 share/web/static/css/main.css
+SHA1 a67bd8704c0c8e8866e01de8a98feb9788b853bd share/web/static/css/main.css
 SHA1 903069dae3de35d6a3226b8272ff317b8eebd58c share/web/static/css/nav.css
 SHA1 45861338bc40888737738521a44d4adf286b1204 share/web/static/css/notices.css
-SHA1 4389605ead1cf3e51a96f69d700ca70b3be6ca32 share/web/static/css/yui/calendar/calendar.css
-SHA1 b8074785c5372a76038c88feed271f1dd839b561 share/web/static/css/yui/tabview/border_tabs.css
-SHA1 2008bf0af63ee36885dd8bbc5fb134bc09b58135 share/web/static/css/yui/tabview/tabs.css
+SHA1 6af7922df30a9bcbba91de135280f35020c3de75 share/web/static/css/yui/calendar/calendar.css
+SHA1 c38a3f0ee9c3177b3b57c8a12259583937596252 share/web/static/css/yui/menu/map.gif
+SHA1 454d5a1fc8a75cfdfda8da84fcdb3ad61bc28ecf share/web/static/css/yui/menu/menu.css
+SHA1 fdb3816246f3a83ea855647ac7522b0fd81fc0f0 share/web/static/css/yui/menu/menuarodwn8_dim_1.gif
+SHA1 e5a3092b0e537c55f6d51fa4a205be40f991c27c share/web/static/css/yui/menu/menuarodwn8_hov_1.gif
+SHA1 49ce21aef759cf5c5c845db503da90be12061f47 share/web/static/css/yui/menu/menuarodwn8_nrm_1.gif
+SHA1 5cd80daf67d57e4ded027501824953e9e1c28c24 share/web/static/css/yui/menu/menuarorght8_dim_1.gif
+SHA1 a5384dbfde3bf5fd601e864a1a3a73f449b84796 share/web/static/css/yui/menu/menuarorght8_hov_1.gif
+SHA1 7946437245912ed7b12586fb9ae304cb34fb2e0a share/web/static/css/yui/menu/menuarorght8_nrm_1.gif
+SHA1 00f9004f9b673c61e0be4017ef4f4fe07d3ad8ba share/web/static/css/yui/menu/menuaroup8_dim_1.gif
+SHA1 88249494fd9e0a44b1f4ec690bb43765bbdddc9c share/web/static/css/yui/menu/menuaroup8_nrm_1.gif
+SHA1 babea44b546e05e156f0808b54e813c6ed611df6 share/web/static/css/yui/menu/menuchk8_dim_1.gif
+SHA1 595dcc3d40dba222b2126d4bda8aa58c655f3eeb share/web/static/css/yui/menu/menuchk8_hov_1.gif
+SHA1 bdbf9997513356f1f4177bc9136f95070a817557 share/web/static/css/yui/menu/menuchk8_nrm_1.gif
+SHA1 e94bf097120743a57f5ab76c35572ce40d354a3f share/web/static/css/yui/tabview/border_tabs.css
+SHA1 ea3e3690200169f41bf24679a3569ad31d664980 share/web/static/css/yui/tabview/tabs.css
+SHA1 4a07b35df98279d126d06236308c29a7bfa69d42 share/web/static/css/yui/tabview/tabview.css
 SHA1 2f28dd2d59fe5486abce194e6fe68da0e49b1084 share/web/static/favicon.ico
 SHA1 6197eb13b4254f77f16833e1a9a8640e939d574c share/web/static/images/css/bullet_arrow_down.png
 SHA1 fdab0053425ba609387dffb0e2529a8feacc3906 share/web/static/images/css/bullet_arrow_up.png
 SHA1 3410d5156716e13443770cce0f3384eacfdb5adb share/web/static/images/css/fieldbg-autocomplete.gif
 SHA1 97c94d7dfb0683f9d2ac7f9406ca36495fa638e0 share/web/static/images/css/fieldbg.gif
+SHA1 a1fdee122b95748d81cee426d717c05b5174fe96 share/web/static/images/iepngfix/blank.gif
 SHA1 67f41db40d62b81d71cb60c542695e0d7e6d393d share/web/static/images/pony.jpg
 SHA1 6197eb13b4254f77f16833e1a9a8640e939d574c share/web/static/images/silk/bullet_arrow_down.png
 SHA1 fdab0053425ba609387dffb0e2529a8feacc3906 share/web/static/images/silk/bullet_arrow_up.png
@@ -425,24 +854,25 @@
 SHA1 eb756c931be8ef70fc27ba0046375f32022e3b6d share/web/static/js/app.js
 SHA1 716b6f8326bd5cd05c31e521351197b5038e052e share/web/static/js/app_behaviour.js
 SHA1 2b28f63068ff486e7fd7937f725f47e886d01831 share/web/static/js/behaviour.js
-SHA1 aa6192ac38a0c708ea0efb60bb98c666d9687423 share/web/static/js/bps_util.js
-SHA1 6b09c590f5e94b238fd99031e6b57ec57e70bd3f share/web/static/js/calendar.js
+SHA1 47cd1a7e3c41b4032cc1712f12b8564cdac12d37 share/web/static/js/bps_util.js
+SHA1 c5fe967d89bc082af093d1ea4eaa2ef3cbfa4e79 share/web/static/js/calendar.js
 SHA1 e9f9931abe8ddf86cf5cfddd1f0e963bb5bf0ccb share/web/static/js/combobox.js
 SHA1 cd5a80e098d28f7cf0b74cee38f08bd336ccdc95 share/web/static/js/context_menu.js
 SHA1 b03b1f06f9c972cfb083c3d87b3dc74e4d85bf77 share/web/static/js/css_browser_selector.js
-SHA1 a90d3ffbc606979282dba3296599f582715021ab share/web/static/js/cssquery/cssQuery-level2.js
-SHA1 ba5ff2e1484476981ccf311ff8fe0062a9b2ac01 share/web/static/js/cssquery/cssQuery-level3.js
+SHA1 efa1e9f561fb31ec520e32e7d623e8e41afb7dfc share/web/static/js/cssquery/cssQuery-level2.js
+SHA1 37cfa3bfdb37450d3a89a88387c4e04baefff271 share/web/static/js/cssquery/cssQuery-level3.js
 SHA1 a80e117cfca6644bde2bb8bd8d48a093e784a731 share/web/static/js/cssquery/cssQuery-standard.js
 SHA1 95408c5aa294bdbc7b857d35772c1bd888b87b33 share/web/static/js/cssquery/cssQuery.js
-SHA1 d542a217ef9c527340d25bfffbccce27927d1259 share/web/static/js/dom-drag.js
+SHA1 e72565db2119b617c9ca0af948956a399caa5720 share/web/static/js/dom-drag.js
 SHA1 4553f3cb184b09228ed4362898e9d30200a2a585 share/web/static/js/formatDate.js
 SHA1 a1d2c6292d656c275383b97aad6ca913b8a1b031 share/web/static/js/halo.js
-SHA1 44bac00f46d4e6809892fc03c42487bd275be71e share/web/static/js/jifty.js
+SHA1 08b20563e958e72c3e8a221d91614c412bdd068b share/web/static/js/iepngfix.htc
+SHA1 8160deda9af812be79ea1f8a30d8cf8d67055777 share/web/static/js/jifty.js
 SHA1 29fe34f11192976f1a388562188b1eb9af7f4497 share/web/static/js/jifty_smoothscroll.js
 SHA1 8723bf251531e79ab109ea0d3fb2187a8dac8cb6 share/web/static/js/jifty_subs.js
-SHA1 2fd261c3c30a0b17e02e6af79d7c7c587dfe2f2a share/web/static/js/jifty_utils.js
-SHA1 d6c17ef3717315c08659082144a2caf2e970b23d share/web/static/js/jsTrace.js
-SHA1 2d8acba4acfd5508381461ccabe954c2e9df086c share/web/static/js/jsan/DOM/Events.js
+SHA1 1a4ccf6b5d376984d91c439e1642bd2b7fb11115 share/web/static/js/jifty_utils.js
+SHA1 49478568d1f258c9d061faa30c2181fd999b07f0 share/web/static/js/jsTrace.js
+SHA1 3b3493afbf46fc8afba58f541e338836bedbdd0b share/web/static/js/jsan/DOM/Events.js
 SHA1 36b2a3f1966b97fcc338b557830106bf2d490485 share/web/static/js/jsan/JSAN.js
 SHA1 679d9c011aa8403cfc0ba945a9143c2e9cacccfa share/web/static/js/jsan/Push.js
 SHA1 4d3474847360cb00edc1ae4745ea6b56a7ec1a2b share/web/static/js/jsan/Upgrade.js
@@ -460,26 +890,16 @@
 SHA1 cc2e31820eed69ae87b1b2befa50e8c4a8519342 share/web/static/js/scriptaculous/slider.js
 SHA1 6b42a40cac7d45f9fd6665e18c4e494704eff9e3 share/web/static/js/scriptaculous/unittest.js
 SHA1 f254696f59ab11c2373c79ba0e6f303d8ac4f71e share/web/static/js/setup_jsan.js
-SHA1 9872547d7c43a3ddb3280fe4e022912b06d59239 share/web/static/js/yui/calendar.js
-SHA1 b378c19c0bbde98f1c7873ca61bb749a63159235 share/web/static/js/yui/container.js
-SHA1 7ddb98d87fa5e228e19c0ce9da2c8d14c8fb8be1 share/web/static/js/yui/dom.js
-SHA1 cb5c1c0e7e8803c95c2f0e313bbeb5a3431f1fba share/web/static/js/yui/event.js
-SHA1 2d81827326f37e25ba95c248498096759f3433c5 share/web/static/js/yui/tabview.js
-SHA1 71c27fdb9e3d24f628a820638ff529098cdd7821 share/web/static/js/yui/yahoo.js
+SHA1 4f45c2546592411e46e149a73d347e176d0c7ad6 share/web/static/js/yui/calendar.js
+SHA1 4d8516305e94d483884ebdfca238d5ea51d0998c share/web/static/js/yui/container.js
+SHA1 dcffe77f6896444b0d71fcb1e8be0ad559256a3e share/web/static/js/yui/dom.js
+SHA1 7b3e21d1cab9fd5da64911838295429d16415797 share/web/static/js/yui/element-beta.js
+SHA1 96f4c1ab0670c62a11e1be261dce68f33064bd67 share/web/static/js/yui/event.js
+SHA1 bfe29fd94ccc2d6b6c008245b3a4ce3f8ed651f2 share/web/static/js/yui/menu.js
+SHA1 ae99956060eb7a5a7b8b0856cd1013a3ef5b0189 share/web/static/js/yui/tabview.js
+SHA1 d246ffa31cb6ef0218be0cbec5fd0ba8438ef6cc share/web/static/js/yui/yahoo.js
 SHA1 05359f0e32b4bebd965707788228704167689d3c share/web/templates/=/subs
-SHA1 5cfcf2d84b5548b2990efa52e51d3f15a47816b4 share/web/templates/__jifty/admin/_elements/nav
-SHA1 6a096f8d324464e6ad6407442faf7b2af0ecdc7e share/web/templates/__jifty/admin/action/dhandler
-SHA1 1b55e3945405d09df59f0a40182f06f8f59a2e97 share/web/templates/__jifty/admin/autohandler
-SHA1 51eb5ec4ebe6ad25eac8461c132193ded8ca2640 share/web/templates/__jifty/admin/fragments/list/header
-SHA1 80a5f7d081589dba73766f86a79145e997500655 share/web/templates/__jifty/admin/fragments/list/list
-SHA1 a73b777585f562210eccba19f007e2ac89b428c4 share/web/templates/__jifty/admin/fragments/list/new_item
-SHA1 ed176f653007f8a08e88355bfd68e1b0fc645723 share/web/templates/__jifty/admin/fragments/list/search
-SHA1 a118ac016c645629ed720d9626b36266089eee58 share/web/templates/__jifty/admin/fragments/list/update
-SHA1 9d339e7acebf3e929b15c1d8b4642ecbddf7f4b6 share/web/templates/__jifty/admin/fragments/list/view
-SHA1 559940ee5c2e5b56f3a438f377ea110018e20b18 share/web/templates/__jifty/admin/index.html
-SHA1 b0ceaf320862d14064c55a17f72e91024690371d share/web/templates/__jifty/admin/model/dhandler
 SHA1 bdaeeff0c2522a8509d4da45be703d1e8cf5c96c share/web/templates/__jifty/autocomplete.xml
-SHA1 bfeb6c28df0bc0c78119c9ff90f8051e5f6adcc2 share/web/templates/__jifty/css/dhandler
 SHA1 da39a3ee5e6b4b0d3255bfef95601890afd80709 share/web/templates/__jifty/empty
 SHA1 f85d8cae8a2df3ee51b868a744a9e9af21925e0c share/web/templates/__jifty/error/_elements/error_text
 SHA1 e2d761b0b92f818eb2bbb91a15cef0a2471d2245 share/web/templates/__jifty/error/_elements/wrapper
@@ -487,20 +907,15 @@
 SHA1 0cf3e3f2f8447ea5f66fd22d325c578448129718 share/web/templates/__jifty/error/dhandler
 SHA1 78e1e0af483fa3bdac2de4e5a9d82486d67b8537 share/web/templates/__jifty/error/error.css
 SHA1 6834dbbfe494846bb3a70f1f8d6735c4f8c1b326 share/web/templates/__jifty/error/mason_internal_error
-SHA1 b8793db1dd47943dc83173f02f2227f9ca310235 share/web/templates/__jifty/halo
-SHA1 7fbdc70a9c0481d1e67b6154178173d434206fd9 share/web/templates/__jifty/js/dhandler
-SHA1 6a50927b6d7c7f5f2048a691299585cb2dd05677 share/web/templates/__jifty/online_docs/autohandler
-SHA1 d0116574b44622720db7a9efc7fafdf4002ed012 share/web/templates/__jifty/online_docs/content.html
-SHA1 bd81ff4e458c5e1a76c131dce40ffd71fd6a76f7 share/web/templates/__jifty/online_docs/index.html
-SHA1 630b516dede6767e8185de8211e6affd7b564cfe share/web/templates/__jifty/online_docs/toc.html
-SHA1 c31026ba4fa88814a705651878cb89f086f43f9d share/web/templates/__jifty/validator.xml
+SHA1 36736d4597f9a4259b84618f49122a3e2c2790a0 share/web/templates/__jifty/halo
+SHA1 d56aea6b4ec690cc9078873da2f93bcbb88d2921 share/web/templates/__jifty/validator.xml
 SHA1 8ec2abf3fb43be8217f7a0af4054cf40f7e1e47e share/web/templates/__jifty/webservices/json
 SHA1 bbe1d4af8ab26a9e7d528d819bb271b591172f3c share/web/templates/__jifty/webservices/xml
 SHA1 c7384fcdf1ee7a3e347388c6619f6aa2f297656e share/web/templates/__jifty/webservices/yaml
 SHA1 8145ab6043a7bbd70e1bfa33e068fb741f4ee3a5 share/web/templates/_elements/header
 SHA1 f36e8e0557117d8fdcebad74694fac718101ce27 share/web/templates/_elements/keybindings
 SHA1 0d84d7af43685d7161fc800a2c8b464b8586c57d share/web/templates/_elements/menu
-SHA1 4da6700ff1fdc390436ff05906f4df979c44d572 share/web/templates/_elements/nav
+SHA1 9a63bfc72a36bc01d3d480d24d695ca5a3fe9169 share/web/templates/_elements/nav
 SHA1 b74c8647eb89e1e189d3cefbbfae51da608edcff share/web/templates/_elements/page_nav
 SHA1 c255d8da7c3eb68fc66f9f7c041c92b247489fcc share/web/templates/_elements/sidebar
 SHA1 bc8991085ddd0c664bb57a1ad4a79e9bca1807ea share/web/templates/_elements/wrapper
@@ -508,8 +923,10 @@
 SHA1 106fc0286e2aff5a01d9a623c37fc807451f2037 share/web/templates/dhandler
 SHA1 347e3ad8491b742c4cd8e63e77fb4cae2152034c share/web/templates/helpers/calendar.html
 SHA1 1bd17a07884f71740a048c41b67ac9b06915bf76 share/web/templates/index.html
+SHA1 c118e782947f715afec7b5cffa4ebc413e990c12 share/web/transform_templates
 SHA1 7f9dae91a9bfc2743eec1d7aaf78e16fc9f1baba t/00-load.t
 SHA1 1e1a7b63b3ea8d2712214eb28b5fe69aae76da1d t/01-dependencies.t
+SHA1 777e40e7d3c591c21883d0ed880df8712dd50ff3 t/01-test-mechanize.t
 SHA1 ade22974f54a6e0991e14be587be0c9797e72ed5 t/01-test-web.t
 SHA1 95fe956e7bae756a7bc25e65a6761ee0c64981e7 t/01-version_checks.t
 SHA1 4fa0e0143339298278c5e22a58236c6b71555508 t/02-connect.t
@@ -523,9 +940,9 @@
 SHA1 0712de44cbe60eea251a1955b0bcb218f22adf4a t/07-limit-actions.t
 SHA1 38ab90a10fc0cbbbfc3205e543312950302f37a2 t/08-client.t
 SHA1 ea9587b57587f6b9b5e02e3d30b96807f7b62200 t/09-url.t
-SHA1 a7e9e7792684ccbd1500b4ad88c97a5bc1f7dd54 t/10-i18n.t
+SHA1 7ca6fdf97c470ec1360425d3121690b9a4e93790 t/10-i18n.t
 SHA1 d571f6fae9d1a33060fda8c89951492a02b1af01 t/11-config-files.t
-SHA1 3b834f5b8a6371c502eb0dc1f1cb9d79a5257c7a t/12-param-schema.t
+SHA1 bd4520e6f2bfdabc6dba2d27e0cb6d33453f82e7 t/12-param-schema.t
 SHA1 59c44900b1cb957d262f96363ceff21b46e0d598 t/99-pod-coverage.t
 SHA1 bb0da54f2b3f2d7955baa41ee458cb3d1887f475 t/99-pod.t
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 t/Continuations/bin/jifty
@@ -554,35 +971,61 @@
 SHA1 14a865ad9c903f69dffa595c463f343dd29f62e2 t/Mapper/share/web/templates/index.html
 SHA1 3b7b51b4428dcbf0b9b1d55c39fd139a3ee4868a t/Mapper/t/00-prototype.t
 SHA1 548bf96ee16a84e3793d89cc0dd68ab67bd03f66 t/Mapper/t/01-raw-api.t
-SHA1 c9c9c8fa7e4284baecf87967eef108715068d249 t/Mapper/t/02-api.t
+SHA1 cdc883e2e3ff2997c1efc01f688638f8d983edd9 t/Mapper/t/02-api.t
+SHA1 5151dae3d7ac5f80dcfaf39fdeea0157af85f189 t/TestApp-Plugin-PasswordAuth/Makefile.PL
+SHA1 f7f44f9a7337def0c97f981073e3ed970851d9ae t/TestApp-Plugin-PasswordAuth/bin/jifty
+SHA1 2ad861771e8cc20e90a5820cb4d3d0837a4fc047 t/TestApp-Plugin-PasswordAuth/etc/config.yml
+SHA1 deb71812bd1042f4ac4260a7b67340ff5f6e5c4d t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/FasterSwallow.pm
+SHA1 f34586dcd0217789759de64af7720695c1d50a9a t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/FavoriteColor.pm
+SHA1 a83f69587be10ffe3191bc04ed94f2b817b54ce4 t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Bootstrap.pm
+SHA1 9f38d7dd23e7568ec3979216f928a0ef7bdee0ed t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/CurrentUser.pm
+SHA1 62e2f19a611b7c87b3abcee1a4653c29caf7bc90 t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Dispatcher.pm
+SHA1 eb74aab3f1577160a69f5d5073ec07da7fda041e t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model/User.pm
+SHA1 7513161b6944b864a0d06f74ce230907e2064cf7 t/TestApp-Plugin-PasswordAuth/t/00-model-User.t
+SHA1 cd358dc97050649f35034d8363590798a543799d t/TestApp-Plugin-PasswordAuth/t/01-tokengen.t
+SHA1 fda1f40fc6869572331ab18da6b57679b847d3f0 t/TestApp-Plugin-PasswordAuth/t/11-current_user.t
+SHA1 e39787081ffb2783de44db32157c6f3bf1631047 t/TestApp-Plugin-PasswordAuth/t/12-signup.t
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 t/TestApp-Plugin-REST/bin/jifty
 SHA1 4762d5e154fcbeb0b188a1ecb90c4997403c9d24 t/TestApp-Plugin-REST/etc/config.yml
 SHA1 61845f11966aadecf3bb885fcc5b33ef66e9637f t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Action/DoSomething.pm
 SHA1 3670c345f54846479d42b9636e0484130e1e72c1 t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Dispatcher.pm
 SHA1 2bc709eb73c4f72267835a06f07de3bc9fe0adba t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Model/Group.pm
-SHA1 4ed01e5665fe265e1d45bfcce37a57e8c3087605 t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Model/User.pm
+SHA1 d98ae3b792d679e71ad61d9281e4c70337fb3593 t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Model/User.pm
 SHA1 5184bbae7c9a4653841156f54b34bac4abf7d54f t/TestApp-Plugin-REST/t/00-model-User.t
 SHA1 3b7b51b4428dcbf0b9b1d55c39fd139a3ee4868a t/TestApp-Plugin-REST/t/00-prototype.t
 SHA1 b6c65e7f47ff136c7d370b85cf01f27537dd81ff t/TestApp-Plugin-REST/t/01-config.t
-SHA1 3e915c7d6a7c7a0fee3246da9b1f8e782b5a317a t/TestApp-Plugin-REST/t/02-basic-use.t
+SHA1 daa99f581a0b42976ce7ae4fe8c3f4d79d799827 t/TestApp-Plugin-REST/t/02-basic-use.t
 SHA1 a7dc1f376cac630ea28d2965e561469deb951cc7 t/TestApp/bin/jifty
 SHA1 f9a9321b803e4f248ecdd86fd71613164c01bd86 t/TestApp/lib/TestApp/Action/DoSomething.pm
 SHA1 f93118ca17be86a7c171ee47864d7149baf7344c t/TestApp/lib/TestApp/Action/DoSomethingElse.pm
 SHA1 6e27f855429d18181d6c5a0de6b83492fa5c6219 t/TestApp/lib/TestApp/CurrentUser.pm
-SHA1 de8a0bb9c5dfe2ceb00f38c6baf66627f3b361b2 t/TestApp/lib/TestApp/Dispatcher.pm
-SHA1 3424b48c4def8e714a6508afa7a43569075131c8 t/TestApp/lib/TestApp/Model/User.pm
+SHA1 7e5dfbfaf1fc9c867e3bb3471597e9d744218949 t/TestApp/lib/TestApp/Dispatcher.pm
+SHA1 5e1331569dbfafb56c4bbd26e0e2ad58e2f3b3cd t/TestApp/lib/TestApp/Model/User.pm
+SHA1 b2d3474949dae7c171157e8697dbb208ef3805f8 t/TestApp/lib/TestApp/Upgrade.pm
+SHA1 0807d39d56ad1c603d5fda36c26f92f32709feb0 t/TestApp/lib/TestApp/View.pm
+SHA1 1a738a666e1bd83a6f6791d069738d0a90e724d4 t/TestApp/lib/TestApp/View/base.pm
+SHA1 0838ac6deac43ed66fb6bfb358051b716e12e7a8 t/TestApp/lib/TestApp/View/instance.pm
 SHA1 67f41db40d62b81d71cb60c542695e0d7e6d393d t/TestApp/share/web/static/images/pony.jpg
+SHA1 5a47fc9c85527214f6eaf2c8f8dd84bfb80fef61 t/TestApp/share/web/templates/concrete.html
 SHA1 1e4b29a138e61f49c1ceffe50c15ed0a087613fc t/TestApp/share/web/templates/currentuser
 SHA1 a2e7bf8d2d52bbaf360af24b4ffc00c68d7e31f2 t/TestApp/share/web/templates/dispatch/basic
 SHA1 d1e244371109ce216bfd6b9ac03374737461577c t/TestApp/share/web/templates/dispatch/basic-show
 SHA1 44795ddb863c9c32c05678bf8288c9816e3366a9 t/TestApp/share/web/templates/dosomethingelse
 SHA1 f5870c2fb3222b86d97f14bdf8155821c887987b t/TestApp/share/web/templates/editform
-SHA1 ef0db81c421ba89231ea6d72f355b7dd8fd5e8e2 t/TestApp/share/web/templates/index.html
+SHA1 9cea9df8bd6b4644b100259b9290f5e52f874d0d t/TestApp/share/web/templates/index.html
 SHA1 2f721db97a3b571d0006f6ed9a0d0c8bffef8642 t/TestApp/share/web/templates/manual_redirect
+SHA1 70e9bbbe8ad7df2db3352073ec840a93c4d6d6fb t/TestApp/share/web/templates/path_test/foo/index.html
+SHA1 4e9416993c5e56de1f9688061648ec6a164b1734 t/TestApp/share/web/templates/path_test/in_both
+SHA1 0aa10de36e1c4b34d3e00ca954d10f2c532a1e25 t/TestApp/share/web/templates/path_test/mason_only
+SHA1 1f95e8e0f677fd2571dfcf6e66688b52f0e22184 t/TestApp/share/web/templates/redirected
+SHA1 55438c7d68b465f08c9774aacacbc2aa62cced8f t/TestApp/share/web/templates/regions/list
+SHA1 cc7e1174609f5ae92b441c4ecf7a4734cf5a9436 t/TestApp/share/web/templates/regions/long
+SHA1 f7b091879df762cccacaf827fbadc1ad4b6294b1 t/TestApp/share/web/templates/regions/short
 SHA1 9a50bb56338896f9cd50b7098a9e28397ad28a34 t/TestApp/share/web/templates/somedir/dhandler
 SHA1 350ab77f7c18d826ed91eaf251f3f80ebd9605ba t/TestApp/t/00-model-User.t
 SHA1 3b7b51b4428dcbf0b9b1d55c39fd139a3ee4868a t/TestApp/t/00-prototype.t
 SHA1 94a1fe86cc34fbdce9087f30a69a859063ca8714 t/TestApp/t/01-config.t
+SHA1 840b50a023f9bc45b2345e0c664949d55d056b15 t/TestApp/t/02-dispatch-show-rule-in-wrong-ruleset.t
 SHA1 6c6726cd87697675c80828825ff34109daec7f86 t/TestApp/t/02-dispatch.t
 SHA1 d438a2c8aa2fa15c80da4f2a44ecfe65856b58f8 t/TestApp/t/03-static.t
 SHA1 dc8e0ea29839c6dd50843d7c95a907874f6d5472 t/TestApp/t/04-sessions.t
@@ -596,15 +1039,21 @@
 SHA1 55ba141d6c73a6dfa7ccccb6cb9f32253ed8decb t/TestApp/t/10-compress.t
 SHA1 18667b3bdcbe7b9dd2715e16c8bbffe51c28548f t/TestApp/t/11-current_user.t
 SHA1 019605c6e627bf65ee3d2ed1b8d2b34fc8e10853 t/TestApp/t/12-search.t
+SHA1 1c80b396277bf78134c2aa3de9e0f375e7efef75 t/TestApp/t/13-page-regions.t
+SHA1 b57b4cf6832d53a3777fe65e56f9ae076f474b0a t/TestApp/t/14-template-paths.t
+SHA1 601af3bb2265d698a458d2f02ca76b1a4f076fe7 t/TestApp/t/15-template-subclass.t
 SHA1 69401ad0579fa743f087731536229d2806dd1d6a t/TestApp/t/config-Cachable
 SHA1 710c4b0faaea46f90a7b071e5396541a59ed0ff1 t/TestApp/t/config-Record
+SHA1 6c16e68284cc30d81eba755c6986675690b78f77 t/TestApp/t/i18n-standalone.t
 SHA1 30274351a6eb9342daef843ffb8a2aafee38afb4 t/TestApp/t/instance_id.t
 SHA1 ee548850452b377e08f36a9269c1b8f7911bdb2d t/TestApp/t/regex_meta_in_path_info.t
+SHA1 f502e4937629f7525cf90cf982cadd29bc60ed5a t/TestApp/t/upgrade.t
+SHA1 aa8319f0acdd5c8e8c60b34d360cff834029e570 t/TestApp/testapp
 SHA1 c8fb21f31b593627b38129ee9dd41eaf9c556ced t/lib/Jifty/SubTest.pm
 -----BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.3 (GNU/Linux)
+Version: GnuPG v1.4.3 (Darwin)
 
-iD4DBQFFromfEi9d9xCOQEYRAjV1AJ9gxbyucs3vXDll+msp25TGsP4ZlwCUDDbz
-1ktLZJXD6wX2Hkn/232QNg==
-=ItK4
+iD8DBQFGLAX/Ei9d9xCOQEYRAnSsAKC6QQRZGQFzdh1RYF6eRAfYxjg1KQCfU8ih
+Lh9Xz380qhLKc6AxFRUaZkM=
+=RTdf
 -----END PGP SIGNATURE-----

Modified: jifty/branches/virtual-models/debian/changelog
==============================================================================
--- jifty/branches/virtual-models/debian/changelog	(original)
+++ jifty/branches/virtual-models/debian/changelog	Mon May  7 16:28:32 2007
@@ -1,4 +1,8 @@
- -- AGOSTINI Yves <agostini at univ-metz.fr>  Fri, 16 Mar 2007 18:22:23 +0100
+jifty (0.70416-1) unstable; urgency=low
+
+  * New cpan release
+
+ -- Agostini yves <agostini at univ-metz.fr>  Sun, 15 Apr 2007 22:59:09 +0200
 
 jifty (0.70317-1) unstable; urgency=low
 

Modified: jifty/branches/virtual-models/debian/control
==============================================================================
--- jifty/branches/virtual-models/debian/control	(original)
+++ jifty/branches/virtual-models/debian/control	Mon May  7 16:28:32 2007
@@ -64,14 +64,14 @@
  libhtml-lint-perl, libhtml-mason-perl (>> 1.31), 
  libwww-perl, libhttp-server-simple-perl (>> 0.26), 
  libhttp-server-simple-recorder-perl, libhash-merge-perl, libhook-lexwrap-perl,
- libipc-pubsub-perl (>> 0.23), libjifty-dbi-perl (>> 0.31),
+ libipc-pubsub-perl (>> 0.23), libjifty-dbi-perl (>> 0.40),
  liblocale-maketext-lexicon-perl, liblog-log4perl-perl,
  libmime-types-perl, libmodule-pluggable-perl (>> 3.1),
  libmodule-corelist-perl, libmodule-refresh-perl,
  libmodule-scandeps-perl, libobject-declare-perl (>> 0.22),
  libparams-validate-perl, libscalar-defer-perl (>> 0.10),
  libstring-koremutake-perl, libsql-reservedwords-perl,
- libtemplate-declare-perl (>> 0.06), 
+ libtemplate-declare-perl (>> 0.07), 
  libtest-base-perl, libuniversal-require-perl, liburi-perl,
  libxml-writer-perl (>> 0.601), libxml-simple-perl,
  libxml-xpath-perl, libversion-perl, libyaml-syck-perl (>> 0.72), 

Added: jifty/branches/virtual-models/doc/notes-on-distributed-operations
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/doc/notes-on-distributed-operations	Mon May  7 16:28:32 2007
@@ -0,0 +1,256 @@
+Asynchrony
+Synchrony
+Syncrony
+Syncron
+
+
+
+client-server sync is easy
+consistent distributed replication is ... harder
+
+how do we guarantee a coherent model of the world after sync?
+two possible models:
+
+    - undo local transactions and replay them in globally unique order
+        (This is the bayou model)
+
+    - calculate big deltas to bring local and remote into sync
+
+        svk pull -l, svk push -l
+
+    - replay remote transactions locally until we conflict or are exhausted
+      then batch until we resolve the conflict automatically or require
+      external intervention, then turn around and do the other side?
+            svk pull, svk push
+
+
+How do we deal with "on transaction" behaviour?
+    Some rules should apply only on "this" replica
+        - Send email when we get an update that matches
+    Some rules should apply only when a record is created or modified by a local update (isn't syncced)
+        - When we create a bug report, create a log entry
+    Some rules should apply only when a record is synced
+        - when we sync in a bug report, extract it's associated patches
+          to the local filesystem in ~/patches/to-apply
+
+Getting toward a consistent result:
+    
+    All bayou replicas move toward 'eventual consistency' using anti-entropy
+    syncs of deltas.
+    "  The Bayou system 
+       guarantees that all servers eventually receive all Writes via the 
+       pair-wise anti-entropy process and that two servers holding the 
+       same set of Writes will have the same data contents."
+
+    "  Two important features of the Bayou system design allows 
+       servers to achieve eventual consistency. First, Writes are per- 
+       formed in the same, well-defined order at all servers. Second, the 
+       conflict detection and merge procedures are deterministic so that 
+       servers resolve the same conflicts in the same manner."
+              
+Merge behaviour:
+
+    Bayou style:
+        'dependency checks' on write -- "Do any of the preconditions for 
+        my attempted write fail?
+        (BayouConflictsSOSPPreprint.pdf)
+        
+        on conflict, run a "merge program" - merge programs are application 
+            specific. bayou defines standard categories of merge programs
+            that developers can treat as templates
+
+        when unresolvable conflicts hit, punt it to the user.
+
+
+        
+    Svn-style:
+        textual merge is fine for simple property databases, but won't 
+        deal with "conflicting appointments"
+
+
+Access control:
+
+ * Authentication
+
+    All updates should be signed by an identity. 
+
+
+        Jesse resolves task 1:
+        "Task 1, status changed from open to resolved" - Signed by 0xAAAA (Jesse)
+
+    When propagating updates delivered to a replica by another identity, updates should carry their full pedigrees.
+       
+        Jesse syncs to clkao:
+        "Task 1, status changed from open to resolved" - Signed by 0xAAAA (Jesse)
+        Clkao syncs to audrey:
+        "Task 1, status changed from open to resolved" - Signed by 0xAAAA (Jesse)
+            - Propagated by 0xBBBB (Clkao) to 0xCCCC (Audreyt) at $TIME
+                Hm. $TIME can't be a timestamp. we don't trust timestamps.
+                Is there any reason to carry full pedigrees? It feels "right"
+                to know how updates get carried around.
+
+    When propagating lumped updates, we probably want to carry the components pedigrees. 
+
+
+    clkao understands all of this stuff a lot better than I do. I'm probably 80% wrong.
+
+
+ * Authorization
+
+    
+
+
+
+Defining characteristics of Bayou:
+	
+	(from eurosigops-96)
+	
+	• Clients can read from and write to any server. 
+	• Servers propagate writes among themselves via a pairwise anti-entropy protocol that permits incremental 
+	progress. 
+	• A new database replica, i.e. server, can be created from any existing replica. 
+	• New conflict detection and resolution procedures can be introduced at any time by clients and their applications. 
+
+
+Bayou propagation of updates:
+
+    a replica has a history of all changes. Changes are defined as 
+    'committed' or 'tentative'.  Tentative changes might get rolled back
+    on conflict....so there's a log of all updates. the database can get
+    rolled back and replayed based on new updates. the order of playback   
+    is globally consistent.
+    
+    we really don't want the distinction between tentative and committed.
+    this would mean that 'lightweight' clients can't be used as a vector 
+    to decrease interserver entropy....it also means that clients can't sync with each other. this is a showstopper.
+
+    sosp-97/AE.pdf describes the bayou anti-entropy replication protocol
+    including an explanationf how to deal with servers which have truncated
+    their write logs. The rollback and insert new transactions scheme 
+    described by AE.pdf sounds an awful lot like what Sam Vilain has been doing with splicing perl history, though presents additional challenges not present in a pure software version control system. the splice can introduce new data that needs to propagate forward.
+
+    While bayou servers are weakly connected, they appear to propagate
+    knowledge of all servers to all other servers.
+
+    In an internet-scale system, this feels like it would be a poor choice.
+
+
+Bayou's global ordering
+
+    The big thing about bayou that scares me is their single global order based on time syncronization.  How do we actually ensure that random clients are globally synced timewise. There's a protocol floating around in my head. I haven't thoguht it through enough to know if it works. And yes, this text buffer is too small to explain it adequately.
+
+
+Connecting to any server:
+    
+        Cool thing about Bayou:
+       Fluid transition between synchronous and asynchronous modes
+       of operations.  Multiple collaborators can connect to distinct
+       servers for typical asynchronous operation, or connect to
+       the same server for âtighterâ synchronous  operationn
+
+Partial Replication:
+
+    How do we deal with letting a client sync only part of the system?
+
+    None of the bayou papers dealt with it at all.
+
+
+"The Dangers of Replication and a Solution ", Microsoft, et al. (gray96danger.pdf)
+
+    Proposes a two-tier solution.  It loses because we don't get mobile to mobile sync 
+
+     mobile nodes maintain two copies of every record:
+        a local version and a best-known master.
+
+     online-connected servers are all closely timesynced and transactions are always applied in order.
+       I haven't read far enough into their paper yet, but I can presume that one server is the designated
+       Master and that in the case of disconnect between Master and other online-connected nodes, the Master
+       wins on any conflict that can't be resolved. but in general, updates are resolved actively.
+
+	"Certainly, there are replicated databases: bibles, phone books, 
+	check books, mail systems, name servers, and so on.  But up- 
+	dates to these databases are managed in interesting ways — 
+	typically in a lazy-master way. Further, updates are not record- 
+	value oriented; rather, updates are expressed as transactional 
+	transformations such as “Debit the account by $50” instead of 
+	“change account from $200 to $150”. "
+		
+	"The two-tier replication scheme begins by assuming there are 
+	two kinds of nodes: 
+	Mobile nodes are disconnected much of the time.  They store a 
+	replica of the database and may originate tentative trans- 
+	actions.  A mobile node may be the master of some data 
+	items. 
+	Base nodes are always connected.  They store a replica of the 
+	database.  Most items are mastered at base nodes. 
+	Replicated data items have two versions at mobile nodes: 
+	Master Version: The most recent value received from the ob- 
+	ject master.  The version at the object master is the master 
+	version, but disconnected or lazy replica nodes may have 
+	older versions. 
+	Tentative Version: The local object may be updated by tenta- 
+	tive transactions.  The most recent value due to local up- 
+	dates is maintained as a tentative value. 
+	Similarly, there are two kinds of transactions: 
+	Base Transaction: Base transactions work only on master 
+	data, and they produce new master data. They involve at 
+	most one connected-mobile node and may involve several 
+	base nodes. 
+	Tentative Transaction: Tentative transactions work on local 
+	tentative data.  They produce new tentative versions. 
+	They also produce a base transaction to be run at a later 
+	time on the base nodes. 
+	
+	
+	
+        
+
+More about authz:
+
+AKA: I CAST PKI. YOUR PROJECT FAILS
+
+
+    Authorization is performed using cryptographically signed assertions:
+
+        Every database has a base "trusted authorizers" property: the public keys of principals allowed to make assertions about it.
+
+        Every database has a list of signed authorization assertions:
+            $PRINCIPAL_KEY_ID has the right $RIGHTNAME for the database with UUID $UUID 
+    
+
+            $RIGHTNAME is one of:
+
+                manage_access (make authz assertions)
+                change_db_model (send cryptographically signed database schema update assertions)
+                create_records  (each of these four CRUD rights can optionally take a table name to check)
+                read_records    (bad idea: allow these signed assertions to include a code chunk used to decide applicability)
+                update_records
+                delete_records
+
+
+            We need to protect against Mallory, the malicious user, who will hang on to his authz assertion even after revocation. So, revocations of signed authz assertions should be kept and propagated like regular authz assertions. Servers must never discard revocations or Mallory's malicious transactions could later be reinjected. How do we handle Mallory's pre-revocation non-malicious transactions?  Presumably all pre-revocation transactions on the replica where the revocation was generated are 
+cryptographically signed by Audrey, the trusted authorizer generating the revocation certificate.
+
+            On every sync, every client should propagate its trust database to the peer. 
+
+        While a local user could modify the "trusted authorizers" property to allow an unauthorized user to commit transactions, 
+i       it would not compromise system integrity as this property would not change on upstream replicas and 
+        transactions from unauthorized users, as well as authz assertions by unknown masters would be discarded.
+        It should be possible for a trusted user (Tony) to sign existing transactions generated by his collaborator Ursula,
+         such that they could be passed to tony's upstream replica with a trusted authorizers list whcih does not include ursula
+
+
+Application behaviour:
+    
+    * Application-specific behaviours are side effects.
+    * Some side effects run when an update is replicated in
+    * Some side effects run when an update is created locally
+    * Some side effects run when an update first enters the system, regardless of whether it's locally created or replicated
+    * Some side effects only cause other database updates. These can _potentially_ be rolled back when the transaction
+      is created
+    * Some side effects perform an external action. These can never be rolled back. They cascade. Once a side effect has taken place, we're stuck with the transaction.
+
+
+
+
+

Added: jifty/branches/virtual-models/doc/talks/DoxoryDemo.tgz
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/doc/talks/oscon.2007.dsls.txt
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/doc/talks/oscon.2007.dsls.txt	Mon May  7 16:28:32 2007
@@ -0,0 +1,798 @@
+#title Jesse Vincent - Best Practical
+Domain Specific Languages in Perl
+---
+#title A bit about DSLs
+DSLs are little languages for specific programming tasks
+---
+DSLs are easier to read
+---
+DSLs are  more expressive
+---
+DSLs let you optimize your code for coding
+---
+Mostly, I'm going to talk about "Englishy" DSLs
+---
+Not all DSLs are Englishy
+---
+SQL
+---
+Regexes
+---
+Excel Macros
+---
+XML config files
+---
+XSL-T
+---
+GraphViz
+---
+...but I've been on an Englishy DSL kick
+---
+DSLs can be implemented in your 'host' language
+---
+(These get called "internal" DSLs)
+---
+DSLs can be implemented outside your 'host' langauge
+---
+(External DSLs)
+---
+Everything I'm going to talk about is Pure Perl (Internal)
+---
+The Ruby community is big on DSLs
+---
+You can make DSLs in Perl, too
+---
+(but it does take more work in Perl)
+---
+How did I get here?
+---
+#title How did I get here?
+Airplane
+---
+Narita Express
+---
+Subway
+---
+Ok, How'd I really get here?
+---
+All started at OSCON 2005
+---
+DHH demonstrated Rails migrations
+---
+#mode ruby
+class AddUserTable < ActiveRecord::Migration
+    def self.up
+      create_table :users do |table|
+        table.column :name, :string
+        table.column :login,  :string
+        table.column :password, :string, :limit => 32
+        table.column :email, :string
+      end
+    end
+
+    def self.down
+      drop_table :users
+    end
+  end
+---
+They looked very sexy
+---
+I was very jealous
+---
+"You can't do this in any other language"
+---
+Never say that to a Perl Hacker
+---
+#title Agenda
+We've made some DSLs
+---
+One for declaring database schema
+---
+(I thought Rails did more. But I never read the manual)
+---
+(It does a lot more than Rails migrations)
+---
+One for web templating
+# loc-ja じゃあいったいどうして?!
+---
+(Yes, another web templating system)
+---
+(Hopefully, this one will provide some closure)
+---
+(You'll see)
+---
+One for making web testing easier
+---
+(It's VERY beta)
+---
+(Perfect for Web 2.0)
+---
+#title
+Jifty::DBI::Schema
+---
+#title Jifty::DBI::Schema - The design process
+Delarative Syntax for an Object Relational Mapper
+---
+Started sketching Jifty::DBI columns
+---
+Started with DBIx::SearchBuilder
+---
+Columns were defined as a hash
+---
+#mode perl
+sub _CoreAccessible {
+    {   id => {
+            read       => 1,
+            sql_type   => 4,
+            length     => 11,
+            is_blob    => 0,
+            is_numeric => 1,
+            type       => 'int(11)',
+            default    => ''
+        },
+        Name => {
+            read       => 1,
+            write      => 1,
+            sql_type   => 12,
+            length     => 200,
+            is_blob    => 0,
+            is_numeric => 0,
+            type       => 'varchar(200)',
+            default    => ''
+        },
+   }
+ ...
+}
+---
+Hashes are kind of ugly
+---
+We spent about a month playing with syntax.
+---
+Our first goal was "feels right"
+---
+Our second goal was "we can implement this"
+---
+I'm going to show you some of our design process
+---
+(It's a mix of code and IRC)
+---
+#mode perl
+$x = Jifty::DBI::SchemaBuilder->new;
+$x->define_blablalb
+$x->bla bla
+---
+#mode perl
+our db_table 'addresses';
+our field name => { 
+	has_type 'varchar'; 
+	has_default 'frank' 
+};
+---
+<chmrr> (by the way, i'm pretty sure we don't get to do the sub-at-the-end thing either... I tried lots of hacky ways to get it working and failed.)
+
+<glasser> yeah, I think we're going to end up having a pseudo-sub that's really a hash behind the scenes 
+---
+#mode perl
+{
+    my $s = Jifty::DBI::SG->import_functions;
+    
+    db_table bla bla bla;
+    field bla;
+    field bar;
+} # $s.DESTROY gets called and unimports db_table/field/...
+---
+(This was astonishingly close to what we do today.)
+---
+#mode perl
+my $schema = Jifty::DBI::RecordSchema->new;
+$schema->for_class(__PACKAGE__);
+
+$schema->field name => { 
+	has_type 'varchar'; 
+	has_default 'Frank'
+}
+
+---
+#mode perl
+
+BEGIN { @ISA = 'Jifty::DBI::Record' }
+use Jifty::DBI::Record; # but this sucks!
+
+use base qw/Jifty::DBI::Record/;
+
+__PACKAGE__->schema_version (0.0001) 
+# (or some other method that does two thing evily).
+---
+<obra> we could tie @ISA
+
+<obra> ...I'm kidding
+---
+<obra> we could tie the symbol table
+
+<obra> ...It just doesn't work
+---
+#mode perl
+use base 'Jifty::DBI::Record';
+Jifty::DBI::Record->___from_code();
+
+db_table 'addresses';
+
+field {
+    called 'name'; # ? 
+}
+--- 
+<glasser> is 
+	
+  "has_type 'string'" 
+
+definitely better than 
+
+  "type => 'string'"  
+
+in your book?
+---
+<obra> how would you do: 
+
+ refers_to_many RT::Tickets by 'owner';
+
+<Robrt> hmm. i thought about this before.  we can do like simon and
+
+ refers_to_many "RT::Tickets by owner";
+
+<Robrt> but I don't really like that.  parsing is lame.
+
+<Robrt> I'm *pretty* sure that we can't get the line you've written to compile.
+---
+<obra> I've got a bad perl5 idea for you. Robert claims it's impossible
+
+<obra> I'm trying to make the syntax "refers_to_many 'BTDT::Model::Tasks' by 'owner';" valid perl5 syntax.
+---
+<audreyt> well, that may be true but you don't want that.
+
+<audreyt> refers_to_many BTDT::Model::Tasks by 'owner'
+
+<audreyt> is more readable and easily implemented.
+
+<audreyt> sub by ($) { by => @_ }
+
+<audreyt> done!
+
+<audreyt> stop thinking classes as strings :)
+---
+<obra> shit! it actually works!
+---
+What we had left:
+---
+the "field foo => sub {};" issue
+--- 
+#mode perl
+
+ # We wanted something that acted like this
+ # But without the ugly 'sub' keyword
+ field email => sub {
+ 
+    has_type 'varchar';
+    has_default 'Frank';
+};
+
+---
+#mode perl
+# We cculd do this, but it used a hash
+# not a block
+
+field phone => {
+    has_type 'varchar';
+};
+
+field employee_id => {
+    refers_to_a Sample::Employee;
+}
+---
+#mode perl
+
+# This is ugly and verbose
+
+package Sample::Employee;
+
+use base qw/Jifty::DBI::Record/;
+
+__PACKAGE__->db_table 'employees';
+
+__PACKAGE__->field name => has_type 'varchar';
+
+__PACKAGE__->field dexterity =>  { has_type 'integer'};
+
+---
+#title In the end...
+We ended up with Jifty::DBI columns
+---
+#mode perl
+use Jifty::DBI::Record schema {
+column auth_token => type is 'text',
+  render as 'Unrendered';
+
+column score => type is 'int',
+  is immutable,
+  label is 'Score';
+
+column time_zone =>
+  label is 'Time zone',
+  since '0.0.12',
+  default is 'America/New_York',
+  valid are formatted_timezones();
+};
+---
+We implemented the DSL twice
+---
+#title 
+Take 1
+---
+#title Take 1
+Jifty::DBI::Schema
+---
+#title Take 1: Jifty::DBI::Schema
+Our first DSL in Perl
+---
+We beat the parser into submission with a few tricks
+---
+Injection of functions
+---
+We saw that a moment ago
+---
+Clever function prototypes
+---
+Let's have a look at that
+---
+#mode perl
+# The syntax we wanted
+
+score => type is 'int',
+  is immutable,
+  default is '0',
+  render as 'text',
+  label is 'Score',
+  since is '0.0.7';
+---
+#mode perl
+# perl -MO=Deparse parses that as:
+
+'is'->type('int', 
+  'immutable'->is, 
+   'is'->default('0', 
+      'as'->render('text', 
+        'is'->label('Score', 
+          'is'->since('0.0.7')))));
+---
+How can we fix that?
+---
+Prototype hacking!
+---
+#mode perl
+sub is ($) { return shift };
+sub as ($) { return shift };
+sub since ($) { }
+sub type ($) { }
+sub render ($) {}
+sub label ($) {}
+sub default ($) {}
+---
+#mode perl
+
+# Now, perl -MO=Deparse parses that as:
+
+ type(is('int')), 
+ is('immutable'), 
+ default(is('0')), 
+ render(as('text')), 
+ label(is('Score')), 
+ since(is('0.0.7'));
+---
+Downsides
+---
+Limited flexibility
+---
+Needs new functions for every attribute
+---
+#title Take 2
+#`mpg123  ~/katamari.mp3`
+Object::Declare
+---
+#title Take 2: Object::Declare
+Katamari for Code
+---
+#mode perl
+use Jifty::DBI::Record schema { 
+
+ column score => type is 'int',
+  is immutable,
+  render as 'text',
+  default is '0',
+  label is 'Score',
+  since is '0.0.7';
+};
+---
+# mode perl
+# perl -MO=Deparse parses that as:
+
+'is'->type('int', 
+  'immutable'->is, 
+   'is'->default('0', 
+      'as'->render('text', 
+	'is'->label('Score', 
+	  'is'->since('0.0.7')))));
+---
+Why fight the parser?
+---
+Perl gives us all the rope we need
+---
+UNIVERSAL:: and ::AUTOLOAD
+---
+What actually happens at compile time:
+
+---
+The 'schema' function in our baseclass takes a code block
+---
+...and returns a closure
+---
+Jifty::DBI::Record::import takes over:
+---
+it takes the closure
+---
+it installs some methods...
+---
+...is::AUTOLOAD and UNIVERSAL::is and as::AUTOLOAD
+---
+it runs the closure
+---
+it hands the result off to a method of your choice
+---
+it removes its magic symbols
+---
+...and then your program gets control back
+---
+#title Jifty::DBI::Schema - end
+That's Jifty::DBI::Schema.
+---
+#title
+Template::Declare
+---
+#title Template::Declare
+A pure Perl Templating Language
+---
+What it looks like
+---
+#mode perl
+template '/pages/mypage.html' => sub {
+    html {
+        head {};
+        body {
+            h1 {'Hey, this is text'};
+            }
+        }
+};
+---
+#mode perl
+template choices => page {
+    h1 { 'My Choices' }
+    dl {
+        my $choices = Doxory::Model::ChoiceCollection->new;
+        $choices->limit(
+            column => 'asked_by',
+            value  => Jifty->web->current_user->id,
+        );
+        while (my $c = $choices->next) {
+            dt { $c->name, ' (', $c->asked_by->name, ')' }
+            dd { b { $c->a } em { 'vs' } b { $c->b } }
+        }
+    }
+};
+---
+But! 
+---
+Content! Templates! 
+---
+Design! Code!
+---
+OMGWTF!? THAT'S WRONG!
+---
+The person who told you it's wrong was lying to you.
+---
+We're Perl hackers
+---
+Why are we writing our templates in another language?
+---
+This is not 1997
+---
+It's 2007
+---
+People use CSS for design now
+---
+Programmers still have to make templates
+---
+Templates run like CODE
+---
+Because they ARE code
+---
+Let's use our CODING tools to work with them
+---
+#mode perl
+#title Refactoring
+
+template 'mypage.html' => page {
+ h1 { 'Two choices' };
+ div { attr { class => 'item' };
+       h2 { 'Item 1'};
+  };
+ div { attr { class => 'item' };
+       h2 { 'Item 2'};
+  };
+}; 
+---
+#title Refactoring
+#mode perl
+
+template 'mypage.html' => page {
+ h1 { 'Two choices' };
+ for ("Item 1", "Item 2") { item($_); }
+};
+
+sub item {
+    my $content = shift;
+    div {
+        attr { class => 'item' };
+        h2 {$content};
+    };
+
+}
+---
+We can refactor templates!
+---
+Have you ever tried to refactor HTML?
+---
+Our HTML is magically valid
+---
+(Syntax errors are...Syntax Errors)
+---
+#title Stashing our templates
+#mode perl
+template '/foo/index.html' => sub {... };
+---
+'sub template' takes a name and a coderef
+---
+But where do we put these?
+---
+We need a global stash
+---
+It needs to be per package 
+(Don't want to mix things together)
+---
+Basically, we need a symbol table
+---
+It's Perl
+---
+We have THE symbol table
+---
+But URLs have characters that are illegal in sub names. :/
+---
+Actually, Perl doesn't care
+---
+#mode perl
+no strict 'refs';
+*{ $class . '::' . $subname } = $coderef;
+---
+That just works.
+---
+Even if your sub is named './\\foo#title <>'
+---
+But how do you call it?
+---
+#mode perl
+# perldoc UNIVERSAL
+---
+CLASS->can( METHOD )
+"can" checks if the object or class has a method called "METHOD".
+If it does then a reference to the sub is returned.
+---
+#title Closures
+Now, about that syntax.
+---
+HTML tags take blocks of content
+---
+Our tag methods take blocks of Perl
+---
+They return closures when you want them to
+---
+They run and output their content when you want them to
+---
+#mode perl
+sub h1 (&;$) {
+  my $code = shift;
+  
+  ...
+
+  if (defined wantarray) {
+    return sub { ...closure around $code...};
+  } else {
+    # Actually do our work, run $code and return the output
+    return $code->();
+  }
+}
+---
+We install methods for every HTML tag
+---
+(Except 'tr'. Anybody know why?)
+---
+#mode perl
+use CGI ();
+install_tag($_) 
+  for ( @CGI::EXPORT_TAGS{
+	qw/:html2 :html3 :html4 
+	   :netscape :form/}
+);
+---
+#title Not everything is roses
+(Here's where it all goes wrong)
+---
+HTML Attributes
+---
+# mode perl
+# What we've got:
+
+div { attr { id => 'my-div'};
+      ...
+};
+
+# and
+
+with ( id => 'my-div'), div {
+...
+};
+---
+# mode perl
+# What I think I'd like:
+
+div ( id => 'my-div' ), { 
+... 
+}
+---
+So, what's the big problem?
+---
+Just change the prototype
+---
+In Perl, the (&) in a prototype MUST come first
+---
+ORZ
+---
+Can anybody help me?
+---
+#title Template::Declare - end
+That's Template::Declare
+---
+#title 
+Test::WWW::Declare
+---
+#title Test::WWW::Declare
+A language for testing web applications
+---
+In early development
+---
+It might change
+---
+Web test scripts are UGLY
+---
+Test::WWW::Declare is PRETTY
+---
+Simple, declarative web testing
+---
+Easy to read
+---
+Easy to write
+---
+Looks more like what users do
+---
+#mode perl
+# Test::WWW::Mechanize
+
+my $server=Jifty::Test->make_server;
+isa_ok($server, 'Jifty::Server');
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new;
+$mech->get_html_ok($URL);
+like($mech->uri, qr{splash}, 
+     'Redirected to splash page');
+---
+The insides are great
+---
+The syntax ain't
+---
+We built on Test::More and WWW::Mechanize
+---
+#mode perl
+
+# Test::WWW::Declare
+
+session "search" => run {
+    flow "google searches work" => check {
+        get 'http://google.com/ncr'; 
+        fill form 'f' => { 
+		q   => 'Squeamish ossifrage' };
+        click button 'Google Search';
+    }
+};
+---
+Regular tests keep running on failure
+---
+Makes no sense when a failure means you lose context
+---
+Every 'check' block aborts on failure
+---
+Abort means 'failing test'
+---
+Every 'session' has a cookie jar and WWW::Mechanize
+---
+#mode perl
+session "check logins" => run {
+    flow "basic connectivity" => check {
+        get 'http://fsck.com';
+        content should match qr{fsck.com};
+        click href qr{book};
+        content should match qr{RT Essentials}i;
+    };
+};
+---
+What's the weird syntax?
+---
+# mode perl
+content should match qr{RT Essentials}i;
+---
+#mode perl
+content should match qr{RT Essentials}i;
+
+#   vs
+
+ok($req->content =~ /RT Essentials/i);
+---
+# mode perl
+# How do we make this valid perl?
+
+content should match qr{RT Essentials}i;
+---
+Prototypes
+---
+#mode perl
+sub match ($) {
+    return shift;
+}   
+---
+#mode perl
+sub should ($) {
+    my $item = shift;
+    return $item;
+}
+---
+#mode perl
+sub content ($) { 
+    my $regex = shift;
+    unless ( mech()->content =~ /$regex/ ) {
+        die "Content did not match $regex";
+    }
+}
+---
+#title Test::WWW::Declare - end
+That's Test::WWW::Declare
+---
+#title Conclusion
+Creating DSLs is lots of fun
+---
+Creating DSLs can be a lot of work
+---
+Creating DSLs helps you learn Perl internals
+---
+Creating DSLs helps find bugs in Perl
+---
+DSLs can make coding more fun
+---
+Challenge: CPAN some Japanese DSLs
+---
+Thanks
+---

Added: jifty/branches/virtual-models/doc/talks/present-slides
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/doc/talks/present-slides	Mon May  7 16:28:32 2007
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+use Term::ANSIScreen qw/:color :cursor :screen :keyboard/;
+use Term::ReadKey;
+use Text::Autoformat;
+our @SLIDES;
+
+load_slides();
+my $counter = 0;
+my $slides_played = {};
+	my $title;
+
+open(my $next_slide, ">/tmp/next_slide");
+select($next_slide);
+$| = 1;
+select(STDOUT);
+
+my $cmd = q{ osascript -e ' tell application "Terminal"' -e ' do script "tail -f /tmp/next_slide"' -e 'end tell' };
+system($cmd);
+while ( $counter <= $#SLIDES ) {
+    my $translation = '';
+
+    my $mode = 'text';
+    my ( $cols, $rows, undef, undef ) = GetTerminalSize();
+    my $slide = $SLIDES[$counter];
+
+    print $next_slide Term::ANSIScreen::cls;
+    print $next_slide locate(1,1);
+    print $next_slide colored("Time: ".scalar localtime()  ."\n", 'blue');
+    print $next_slide colored("Back 1\n", 'red');
+    print $next_slide $SLIDES[$counter-1] ."\n\n";
+    print $next_slide colored("This slide, $counter/".$#SLIDES."\n", 'blue');
+    print $next_slide $SLIDES[$counter] ."\n\n";
+    print $next_slide colored("Next slide\n", 'red');
+    print $next_slide $SLIDES[$counter+1];
+    print $next_slide "\n";	
+
+    my $console = Term::ANSIScreen->new;
+    $console->Cls;
+    $console->Cursor(1,1);
+    if ( $slide =~ s/^#\s*title\s*?(.*?)$//gm ) {
+        $title = $1;
+    }
+	if ($title) {
+        my $start = int ( ( $cols / 2 ) - ( length($title) / 2 ) );
+	$console->Cursor($start,0);
+	chomp $title;
+	print "$title\n";
+	}
+
+    if ($slide =~ s/#\s*loc-ja\s*(.*?)$//sm) {
+	$translation = $1;
+    }
+    if ($slide =~ s/#\s*`(.*?)`//m) {
+	my $cmd = $1;
+	if(!$slides_played->{$counter}) {
+	`$cmd>/dev/null 2>/dev/null &`;
+	$slides_played->{$counter}++}
+    }
+    if ( $slide =~ s/#\s*mode.*?(perl|ruby).*?$//gms ) {
+        $mode = $1;
+    }
+    if ( $mode eq 'text' and $slide ) {
+        $slide = autoformat $slide, { left => 2, right => ($cols-1), all => 1 };
+    }
+    elsif ($mode =~ /(?:perl|ruby)/) {
+	$slide =~ s/^/ /gsm;
+	my $tidycols = $cols - 2; # squeeze for display
+	open my $out , ">/tmp/output.$$" || die $!;
+	print $out $slide || die $!;
+	close $out || die $!;
+	$slide = ` cat /tmp/output.$$ | source-highlight -s $mode -f esc`;
+	#$slide = ` cat /tmp/output.$$ | perltidy -q -l $tidycols| source-highlight -s perl -f esc`;
+    }
+ 
+    if ( $slide =~ /(\S+)\s*\n\s*(\S+)/m ) {
+	my $lines = ($slide =~ tr/\n//);
+	$console->Cursor(0, int(($rows/2)-($lines/2))-1);
+    	print $slide;
+    } else {
+	chomp $slide;
+	$slide =~ s/(?:\n|\r)//g;
+		my $left = int ( ( $cols / 2 ) - ( length($slide) / 2 ) ); 
+	if ($left < 0 ){
+		$left = 0;
+	}
+        $console->Cursor( $left,	int($rows/2)-1, );
+	print  colored($slide." \n",'bold blue on white');
+    }
+
+
+    $console->Cursor( 0, ( $rows - 1 ) );
+    print colored("$counter/" . $#SLIDES, "bold white");
+    if ($translation) {
+        my $start = int ( ( $cols / 2 ) - ( length($translation) / 2 ) );
+    	$console->Cursor( $start , ( $rows - 1 ) );
+    	print colored($translation, "bold yellow on black");
+   }
+    ReadMode 4;
+    my $key = ReadKey(0);
+    ReadMode 0;
+    if ( $key eq 'q' ) {
+        exit;
+    }
+    if ( $key =~ /^(?: |\n|n)/ ) {
+        $counter++;
+    } elsif ( $key eq 'e' ) {
+	system("vim", $ARGV[0]);
+	load_slides();
+	next;
+    } elsif ( $key eq 'r' ) {
+	load_slides();
+        next;
+
+    } else {
+        $counter--;
+        if ( $counter < 0 ) {
+            $counter = 0;
+        }
+    }
+}
+
+sub load_slides {
+my $file = $ARGV[0];
+my $handle;
+open( $handle, "<$file" ) || die $!;
+
+my $datadata = join( '', <$handle> );
+
+ @SLIDES  = split( /^----?\s*$/mi, $datadata );
+}

Added: jifty/branches/virtual-models/doc/talks/yapc.asia.2007.ja.txt
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/doc/talks/yapc.asia.2007.ja.txt	Mon May  7 16:28:32 2007
@@ -0,0 +1,934 @@
+#title Jesse Vincent - Best Practical
+Domain Specific Languages in Perl
+# loc-ja: PerlでDSL
+---
+#title A bit about DSLs
+# loc-ja: DSLってなに?
+DSLs are little languages for specific programming tasks
+# loc-ja: 決まった分野の仕事をさせるための専用ミニ言語
+---
+DSLs are easier to read
+# loc-ja: DSLにすると読みやすい
+---
+DSLs are  more expressive
+# loc-ja: 表現力も増す
+---
+DSLs let you optimize your code for coding
+# loc-ja: コーディングしやすいようにコードを最適化できる
+---
+Mostly, I'm going to talk about "Englishy" DSLs
+# loc-ja: 今日は「英語っぽく読めるようにする」DSLの話をするけど
+---
+Not all DSLs are Englishy
+# loc-ja: DSLだからって全部英語っぽくなっているわけじゃない
+---
+Excel Macros
+# loc-ja: Excelのマクロ
+---
+XML config files
+# loc-ja: XMLの設定ファイル
+---
+XSL-T
+---
+GraphViz
+---
+...but I've been on an Englishy DSL kick
+# loc-ja: ただ、自分はいま英語っぽく読めるようにするDSLにハマってる
+---
+DSLs can be implemented in your 'host' language
+# loc-ja: DSLは「ホスト」になる言語で実装することもできる
+---
+(These get called "internal" DSLs)
+# loc-ja: こういうのは「内部」DSLと呼ばれる
+---
+DSLs can be implemented outside your 'host' langauge
+# loc-ja: 「ホスト」言語以外のもので実装することもできる
+---
+(External DSLs)
+# loc-ja: こういうのは外部DSLだ
+---
+Everything I'm going to talk about is Pure Perl (Internal)
+# loc-ja: 今日話すのはPure Perlのもの(だから内部DSLだね)
+---
+The Ruby community is big on DSLs
+# loc-ja: DSLの大家といえばRubyのコミュニティだけど
+---
+You can make DSLs in Perl, too
+# loc-ja: PerlでDSLをつくることもできる
+---
+(but it does take more work in Perl)
+# loc-ja: Perlの方がちょっと手間がかかるけど
+---
+#title How did I get here?
+# loc-ja: ここに至るまでの道のり?
+Airplane
+# loc-ja: 飛行機
+---
+Narita Express
+# loc-ja: それから成田エクスプレス
+---
+Subway
+# loc-ja: それから地下鉄
+---
+Ok, How'd I really get here?
+# loc-ja: 冗談はさておき
+---
+All started at OSCON 2005
+# loc-ja: 発端はOSCON 2005だった
+---
+DHH demonstrated Rails migrations
+# loc-ja: DHHがRailsのマイグレーションのデモを見せてくれたんだけど
+---
+they looked very sexy
+# loc-ja: それが実にイカしていたわけだ
+---
+I was very jealous
+# loc-ja: むちゃくちゃうらやましかった。でも…
+---
+"You can't do this in any other language"
+# loc-ja: 「こんなことほかの言語じゃできないでしょ」
+---
+Never say that to a Perl Hacker
+# loc-ja: Perlハッカーにそんなことを言っちゃいけないよね
+---
+#title Agenda
+# loc-ja: アジェンダ
+We've made some DSLs
+# loc-ja: Best Practical社でもいくつかDSLをつくっている
+---
+One for declaring database schema
+# loc-ja: ひとつはデータベースのスキーマを宣言するためのもの
+---
+(I thought Rails did more. But I never read the manual)
+# loc-ja: Railsはもっといろいろしていたと思うけど、Railsのマニュアルなんて読んだことない
+---
+(It does a lot more than Rails migrations)
+# loc-ja: でも、Railsのマイグレーションよりははるかにいろんなことをしているよ
+---
+One for web templating
+# loc-ja: もうひとつはウェブテンプレート用
+---
+(Yes, another web templating system)
+# loc-ja: そう、またしても新しいウェブテンプレートシステムをつくったんだ
+---
+(Hopefully, this one will provide some closure)
+# loc-ja: できれば今度のはクロージャも使えるようにするつもり
+---
+(You'll see)
+# loc-ja: お楽しみに
+---
+One for making web testing easier
+# loc-ja: もうひとつはライブテストをもっと簡単にするためのもの
+---
+(It's VERY beta)
+# loc-ja: これはほんとにベータなんだけど
+---
+(Perfect for Web 2.0)
+# loc-ja: Web 2.0にはうってつけ
+---
+#title 
+Jifty::DBI::Schema
+---
+#title Jifty::DBI::Schema - The design process
+# loc-ja: Jifty::DBI::Schema ができるまで
+Delarative Syntax for an Object Relational Mapper
+# loc-ja: オブジェクトリレーショナルマッパ用の宣言指向なシンタックス
+---
+Started sketching Jifty::DBI columns
+# loc-ja: Jifty::DBIのカラムをどうするか、ざっと書いてみた
+---
+Started with DBIx::SearchBuilder
+# loc-ja: とりあえずDBIx::SearchBuilderで
+---
+Columns were defined as a hash
+# loc-ja: カラムの定義はハッシュ
+---
+Hashes are ugly
+# loc-ja: でも、ハッシュはダサい
+---
+We spent about a month playing with syntax.
+# loc-ja: 一ヶ月くらいシンタックスをいじっていたかな
+---
+Our first goal was "feels right"
+# loc-ja: 最初のゴールは「これなら悪くない」と思えるようにすること
+---
+Our second goal was "we can implement this"
+# loc-ja: 次のゴールは「これなら実装できる」というものにすること
+---
+I'm going to show you some of our design process
+# loc-ja: じゃあ、どうやってデザインしたか
+---
+(It's a mix of code and IRC)
+# loc-ja: コードとIRCを織りまぜて紹介します
+---
+#mode perl
+$x = Jifty::DBI::SchemaBuilder->new;
+$x->define_blablalb
+$x->bla bla
+---
+#mode perl
+our db_table 'addresses';
+our field name => { 
+	has_type 'varchar'; 
+	has_default 'frank' 
+};
+---
+<chmrr> (by the way, i'm pretty sure we don't get to do the sub-at-the-end thing either... I tried lots of hacky ways to get it working and failed.)
+# loc-ja: ところで「プロトタイプの最後にサブルーチンを入れる」ってできないよね…いろいろハックしてみたけどだめだった
+
+<glasser> yeah, I think we're going to end up having a pseudo-sub that's really a hash behind the scenes 
+# loc-ja: うん、結局疑似subを使うことになりそうだよ。実際にはハッシュなんだけどね
+---
+#mode perl
+{
+    my $s = Jifty::DBI::SG->import_functions;
+    
+    db_table bla bla bla;
+    field bla;
+    field bar;
+} # $s.DESTROY gets called and unimports db_table/field/...
+# loc-ja: ここで$s.DESTROYが呼ばれてdb_table/field/...とかをアンインポートする
+---
+(This was astonishingly close to what we do today.)
+# loc-ja: これはびっくりするほどいまの形に近い
+---
+#mode perl
+my $schema = Jifty::DBI::RecordSchema->new;
+$schema->for_class(__PACKAGE__);
+
+$schema->field name => { 
+	has_type 'varchar'; 
+	has_default 'Frank'
+}
+---
+#mode perl
+
+BEGIN { @ISA = 'Jifty::DBI::Record' }
+use Jifty::DBI::Record; # but this sucks!
+
+use base qw/Jifty::DBI::Record/;
+
+__PACKAGE__->schema_version (0.0001) 
+# (or some other method that does two thing evily).
+# loc-ja: この2つをうまいことしてくれる邪悪な方法はないかな
+---
+<obra> we could tie @ISA
+# loc-ja: @ISAをtieできたらいいんだけどな
+
+<obra> ...I'm kidding
+# loc-ja: …いや、冗談だって
+---
+<obra> we could tie the symbol table
+# loc-ja: シンボルテーブルをtieできたらいいんだけど
+
+<obra> ...It just doesn't work
+# loc-ja: …動かないね
+---
+#mode perl
+use base 'Jifty::DBI::Record';
+Jifty::DBI::Record->___from_code();
+
+db_table 'addresses';
+
+field {
+    called 'name'; # ? 
+}
+--- 
+<glasser> is 
+	
+  "has_type 'string'" 
+
+definitely better than 
+
+  "type => 'string'"  
+
+in your book?
+# loc-ja: "has_type 'string'" より "type => 'string'" の方がずっといいんじゃない?
+---
+<obra> how would you do: 
+# loc-ja: じゃあ、こんなのはどうする?
+
+ refers_to_many RT::Tickets by 'owner';
+
+<Robrt> hmm. i thought about this before.  we can do like simon and
+# loc-ja: 前に考えたことあるけど、simonのようにすればいいかな
+
+ refers_to_many "RT::Tickets by owner";
+
+<Robrt> but I don't really like that.  parsing is lame.
+# loc-ja: でも、あまりよくはないよね。パースなんてしたくない
+
+<Robrt> I'm *pretty* sure that we can't get the line you've written to compile.
+# loc-ja: でも、Jesseが書いたのは絶対にコンパイルできないんじゃないかと思うよ
+---
+<obra> I've got a bad perl5 idea for you. Robert claims it's impossible
+# loc-ja: 悪いことを思いついたんだ。Robertは絶対にできないって言ってるけど
+
+<obra> I'm trying to make the syntax "refers_to_many 'BTDT::Model::Tasks' by 'owner';" valid perl5 syntax.
+# loc-ja: 自分は "refers_to_many 'BTDT::Model::Tasks' by 'owner';" というのをperl5のシンタックスとして通るものにしようと思ってる
+---
+<audreyt> well, that may be true but you don't want that.
+# loc-ja: うーん、それでもいいけど、そんなことしなくてもいいよ
+
+<audreyt> refers_to_many BTDT::Model::Tasks by 'owner'
+
+<audreyt> is more readable and easily implemented.
+# loc-ja: の方が読みやすいし実装しやすいもの
+
+<audreyt> sub by ($) { by => @_ }
+
+<audreyt> done!
+# loc-ja: ほらできた!
+
+<audreyt> stop thinking classes as strings :)
+# loc-ja: クラスを文字列だなんて思わなければいい :)
+---
+<obra> shit! it actually works!
+# loc-ja: なんてこった! ほんとにできてる!
+---
+
+What we had left:
+# loc-ja: そうなると、残るは
+
+the field foo => sub {}; issue
+# loc-ja: field foo => sub {}; の問題か
+--- 
+#mode perl
+
+ # We wanted something that acted like this
+ # But without the ugly 'sub' keyword
+ field email => sub {
+ 
+    has_type 'varchar';
+    has_default 'Frank';
+};
+
+# loc-ja: みっともない'sub'なんてなしでこんな風に動くのがほしいね
+---
+#mode perl
+# We could do this, but it used a hash
+# not a block
+
+field phone => {
+    has_type 'varchar';
+};
+
+field employee_id => {
+    refers_to_a Sample::Employee;
+}
+# loc-ja: こんな風にしてもいいけど、ブロックじゃなくてハッシュになっちゃう
+---
+#mode perl
+
+# This is ugly and verbose
+
+package Sample::Employee;
+
+use base qw/Jifty::DBI::Record/;
+
+__PACKAGE__->db_table 'employees';
+
+__PACKAGE__->field name => has_type 'varchar';
+
+__PACKAGE__->field dexterity =>  { has_type 'integer'};
+
+# loc-ja: これだとみっともないし、くどいな
+---
+#title In the end...
+# loc-ja: 結局…
+
+We ended up with Jifty::DBI columns
+# loc-ja: Jifty::DBIのカラムはこんな風になった
+---
+#mode perl
+use Jifty::DBI::Record schema {
+column auth_token => type is 'text',
+  render as 'Unrendered';
+
+column score => type is 'int',
+  is immutable,
+  label is 'Score';
+
+column time_zone =>
+  label is 'Time zone',
+  since '0.0.12',
+  default is 'America/New_York',
+  valid are formatted_timezones();
+};
+---
+Implemented it twice
+# loc-ja: これ、実は2回実装している
+---
+#title 
+Take 1
+# loc-ja: 最初の実装はこう
+---
+#title Take 1
+# loc-ja: 最初の実装
+Jifty::DBI::Schema
+---
+#title Take 1: Jifty::DBI::Schema
+# loc-ja: 最初の実装: Jifty::DBI::Schema
+Our first DSL in Perl
+# loc-ja: Best Practical社がはじめてPerlで書いたDSL
+---
+We beat the parser into submission with a few tricks
+# loc-ja: パーサに言うことを聞かせるためにいくつかトリックを使ってる
+---
+Injection of functions
+# loc-ja: 関数の埋め込み
+---
+We saw that a moment ago
+# loc-ja: これはさっき見たよね
+---
+Clever function prototypes
+# loc-ja: 上手な関数プロトタイプ
+---
+Let's have a look at that
+# loc-ja: ちょっと説明しよう
+---
+#mode perl
+# The syntax we wanted
+
+score => type is 'int',
+  is immutable,
+  default is '0',
+  render as 'text',
+  label is 'Score',
+  since is '0.0.7';
+# loc-ja: こんなシンタックスにしたい
+---
+#mode perl
+# perl -MO=Deparse parses that as:
+
+'is'->type('int', 
+  'immutable'->is, 
+   'is'->default('0', 
+      'as'->render('text', 
+        'is'->label('Score', 
+          'is'->since('0.0.7')))));
+# loc-ja: perl -MO=Deparse をするとこんな風にパースされてしまう
+---
+How can we fix that?
+# loc-ja: どうすれば直せるだろう?
+---
+Prototype hacking!
+# loc-ja: プロトタイプをハックすればいい!
+---
+#mode perl
+sub is ($) { return shift };
+sub as ($) { return shift };
+sub since ($) { }
+sub type ($) { }
+sub render ($) {}
+sub label ($) {}
+sub default ($) {}
+---
+#mode perl
+
+# Now, perl -MO=Deparse parses that as:
+
+ type(is('int')), 
+ is('immutable'), 
+ default(is('0')), 
+ render(as('text')), 
+ label(is('Score')), 
+ since(is('0.0.7'));
+# loc-ja: これで perl -MO=Deparse はこんな風になる
+---
+Downsides
+# loc-ja: これの欠点
+- Limited flexibility
+# loc-ja: 柔軟性に欠ける
+- Needs new functions for every attribute
+# loc-ja: 属性をつくるたびに新しい関数が必要になる
+---
+#title Take 2
+# loc-ja: 2度目の実装
+#`mpg123  ~/katamari.mp3`
+Object::Declare
+---
+#title Take 2: Object::Declare
+# loc-ja: 2度目の実装: Object::Declare
+Katamari for Code
+# loc-ja: コードの塊
+---
+#mode perl
+use Jifty::DBI::Record schema { 
+
+ column score => type is 'int',
+  is immutable,
+  render as 'text',
+  default is '0',
+  label is 'Score',
+  since is '0.0.7';
+};
+---
+# mode perl
+# perl -MO=Deparse parses that as:
+
+'is'->type('int', 
+  'immutable'->is, 
+   'is'->default('0', 
+      'as'->render('text', 
+	'is'->label('Score', 
+	  'is'->since('0.0.7')))));
+# loc-ja: perl -MO=Deparse するとこんな風になる
+---
+Why fight the parser?
+# loc-ja: どうしてパーサなんて相手にしていたんだろう?
+---
+Perl gives us all the rope we need
+# loc-ja: Perlには必要な手が揃ってるじゃないか
+---
+UNIVERSAL:: and ::AUTOLOAD
+# loc-ja: UNIVERSAL:: と ::AUTOLOAD だ
+---
+What actually happens at compile time:
+
+# loc-ja: これをコンパイルすると、裏ではどんなことが起こるのか?
+---
+The 'schema' function in our baseclass takes a code block
+# loc-ja: ベースクラスの'schema'関数がコードブロックを受け取り
+---
+...and returns a closure
+# loc-ja: クロージャを返す
+---
+Jifty::DBI::Record::import takes over:
+# loc-ja: 続いてJifty::DBI::Record::importが
+---
+it takes the closure
+# loc-ja: そのクロージャを受け取り、
+---
+it installs some methods...
+# loc-ja: いくつかのメソッドをインストールして
+---
+...is::AUTOLOAD and UNIVERSAL::is and as::AUTOLOAD
+# loc-ja: is::AUTOLOAD とか UNIVERSAL::is とか as::AUTOLOAD とかね
+---
+it runs the closure
+# loc-ja: クロージャを実行して
+---
+it hands the result off to a method of your choice
+# loc-ja: 結果をお望みのメソッドに渡す
+---
+it removes its magic symbols
+# loc-ja: それからマジックシンボルを削除して
+---
+...and then your program gets control back
+# loc-ja: プログラムにコントロールを戻す
+---
+#title Jifty::DBI::Schema - end
+# loc-ja: Jifty::DBI::Schema - おしまい
+That's Jifty::DBI::Schema.
+# loc-ja: Jifty::DBI::Schema はこんな感じ
+---
+#title
+Template::Declare
+---
+#title Template::Declare
+A pure Perl Templating Language
+# loc-ja: pure Perlのテンプレート言語
+---
+What it looks like
+# loc-ja: こんなの
+---
+#mode perl
+template '/pages/mypage.html' => sub {
+    html {
+        head {};
+        body {
+            h1 {'Hey, this is text'};
+            }
+        }
+};
+---
+But! 
+# loc-ja: でもね!
+---
+Content! Templates! 
+# loc-ja: コンテンツ! テンプレート!
+---
+Design! Code!
+# loc-ja: デザイン! コード!
+---
+OMGWTF!? THAT'S WRONG!
+# loc-ja: なんだって!? 冗談じゃない!
+---
+The person who told you it's wrong was lying to you.
+# loc-ja: みなさんにこういうのはダメだなんて言った人は嘘つきです
+---
+We're perl hackers
+# loc-ja: 私たちはperlハッカーなんだから
+---
+Why are we writing our templates in another language?
+# loc-ja: どうしてほかの言語でテンプレートを書かなきゃいけないの?
+---
+This is not 1997
+# loc-ja: 1997年じゃないんだよ
+---
+It's 2007
+# loc-ja: 2007年なんだから
+---
+People use CSS for design now.
+# loc-ja: CSS使ってデザインしてるでしょ
+---
+Programmers still have to make templates
+# loc-ja: それでもプログラマはテンプレートをつくらないといけないけど
+---
+Templates run like CODE
+# loc-ja: テンプレートはコードのような働きをするもの
+---
+Because they ARE code
+# loc-ja: だって、実際コードだからね
+---
+Let's use our CODING tools to work with them.
+# loc-ja: それならコードを書くときに使う道具でなんとかしよう
+---
+#mode perl
+#title Refactoring
+# loc-ja: リファクタリング
+
+template 'mypage.html' => page {
+ h1 { 'Two choices' };
+ div { attr { class => 'item' };
+       h2 { 'Item 1'};
+  };
+ div { attr { class => 'item' };
+       h2 { 'Item 2'};
+  };
+}; 
+---
+#title Refactoring
+# loc-ja: リファクタリング
+#mode perl
+
+template 'mypage.html' => page {
+ h1 { 'Two choices' };
+ for ("Item 1", "Item 2") { item($_); }
+};
+
+sub item {
+    my $content = shift;
+    div {
+        attr { class => 'item' };
+        h2 {$content};
+    };
+
+}
+---
+We can refactor templates!
+# loc-ja: テンプレートのリファクタリングもできるよ!
+---
+Have you ever tried to refactor HTML?
+# loc-ja: HTMLのリファクタリングなんてしたことある?
+---
+Our HTML is magically valid.
+# loc-ja: うちのHTMLは魔法がかかっているからいつでも正しい
+(Syntax errors are...Syntax Errors)
+# loc-ja: シンタックスエラーは…シンタックスエラーになる
+---
+#title Stashing our templates
+# loc-ja: テンプレートをスタッシュに入れよう
+#mode perl
+template '/foo/index.html' => sub {... };
+---
+'sub template' takes a name and a coderef
+# loc-ja: 'sub template'はテンプレート名とコードリファレンスを取る
+---
+But where do we put these?
+# loc-ja: でも、これをどこに入れよう?
+---
+We need a global stash.
+# loc-ja: グローバルなスタッシュが要るね
+---
+It needs to be per package 
+# loc-ja: パッケージ単位でなくちゃいけない
+(Don't want to mix things together)
+# loc-ja: ごちゃまぜにはしたくないから
+---
+Basically, we need a symbol table
+# loc-ja: 基本的にはシンボルテーブルがあればいいわけだけれど
+---
+It's Perl
+# loc-ja: Perlなんだから
+---
+We have THE symbol table
+# loc-ja: シンボルテーブルそのものはある
+---
+But URLs have characters that are illegal in sub names. :/
+# loc-ja: ただ、URLには関数名としては不適切な文字が含まれているんだよね :/
+---
+Actually, Perl doesn't care
+# loc-ja: でも、実はこれ、Perlは気にしない
+---
+#mode perl
+    no strict 'refs';
+    *{ $class . '::' . $subname } = $coderef;}
+---
+That just works.
+# loc-ja: これで問題なく動いてしまう
+---
+Even if your sub is named './\\foo#title <>'
+# loc-ja: サブルーチンの名前が'./\\foo#title <>'だったとしてもだ
+---
+But how do you call it?
+# loc-ja: でも、そんなのどうやって呼び出せばいい?
+---
+# perldoc UNIVERSAL
+
+CLASS->can( METHOD )
+"can" checks if the object or class has a method called "METHOD".
+If it does then a reference to the sub is returned.
+# loc-ja: "can"はオブジェクトないしクラスが"METHOD"というメソッドを持っているかチェックして、持っている場合はそのサブルーチンへのリファレンスを返します
+---
+#title Closures
+# loc-ja: クロージャ
+Now, about that syntax.
+# loc-ja: 今度はそのシンタックスの話
+---
+HTML tags take blocks of content.
+# loc-ja: HTMLタグはコンテンツのブロックを取る
+---
+Our tag methods take blocks of perl.
+# loc-ja: うちのタグメソッドはperlのブロックを取る
+---
+They return closures when you want them to
+# loc-ja: そうしたければクロージャを返させることもできる
+---
+#mode perl
+sub h1 (&;$) {
+  my $code = shift;
+  
+  ...
+
+  if (defined wantarray) {
+    return sub { ...closure around $code...};
+  } else {
+    # Actually do our work, run $code and return the output
+  }
+}
+---
+We install methods for every HTML tag
+# loc-ja: うちのはあらゆるHTMLタグにメソッドをインストールする
+---
+(Except 'tr'. Anybody know why?)
+# loc-ja: 'tr' 以外ね。理由はわかる?
+---
+#mode perl
+use CGI ();
+install_tag($_) 
+  for ( @CGI::EXPORT_TAGS{
+	qw/:html2 :html3 :html4 
+	   :netscape :form/}
+);
+---
+#title Not everything is roses
+# loc-ja: すべてがバラ色というわけではない
+(Here's where it all goes wrong)
+# loc-ja: ここがみんなハマるところだ
+---
+HTML Attributes
+# loc-ja: HTMLアトリビュート
+---
+# mode perl
+# What we've got:
+
+div { 
+        attr { id => 'my-div'};
+    ...
+};
+
+# and
+
+with ( id => 'my-div'), div {
+...
+};
+# loc-ja: こんな風にはできていた
+---
+# mode perl
+# What I think I'd like:
+
+div ( id => 'my-div' ), { 
+... 
+}
+# loc-ja: こうしたいな
+---
+So, what's the big problem?
+# loc-ja: ここで大きな問題になったのは
+---
+Just change the prototype.
+# loc-ja: 単にプロトタイプを変えるだけだと
+---
+In Perl, the (&) in a prototype
+may ONLY come first. 
+# loc-ja: Perlの場合、プロトタイプの(&)は最初に「しか」置けないということだ
+---
+ORZ
+---
+Can anybody help me?
+# loc-ja: 誰か名案ない?
+---
+#title Template::Declare - end
+# loc-ja: Template::Declare - おしまい
+That's Template::Declare
+# loc-ja: Template::Declareについてはこの辺で
+---
+#title 
+Test::WWW::Declare
+---
+#title Test::WWW::Declare
+A language for testing web applications
+# loc-ja: ウェブアプリケーションのテスト用言語
+---
+In early development
+# loc-ja: 開発は始まったばかりなので
+---
+It might change
+# loc-ja: 内容は変わるかも
+---
+Web test scripts are UGLY
+# loc-ja: ウェブテストスクリプトってほんとに汚いよね
+---
+Test::WWW::Declare is PRETTY
+# loc-ja: Test::WWW::Declareはきれいだ
+---
+Simple, declarative web testing
+# loc-ja: シンプルな、宣言指向のウェブテスト
+---
+Easy to read
+# loc-ja: 読みやすい
+---
+Easy to write
+# loc-ja: 書きやすい
+---
+Looks more like what users do
+# loc-ja: ユーザがしている通りに見える
+---
+#mode perl
+# Test::WWW::Mechanize
+
+my $server=Jifty::Test->make_server;
+isa_ok($server, 'Jifty::Server');
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new;
+$mech->get_html_ok($URL);
+like($mech->uri, qr{splash}, 
+     'Redirected to splash page');
+---
+The insides are great
+# loc-ja: 中身はすごいよ
+---
+The syntax ain't
+# loc-ja: シンタックスはそうでもない
+---
+We built on Test::More and WWW::Mechanize
+# loc-ja: これ、Test::More と WWW::Mechanize が下敷きになっている
+---
+#mode perl
+
+# Test::WWW::Declare
+
+session "search" => run {
+    flow "google searches work" => check {
+        get 'http://google.com/ncr'; 
+        fill form 'f' => { 
+		q   => 'Squeamish ossifrage' };
+        click button 'Google Search';
+    }
+};
+---
+Regular tests keep running on failure
+# loc-ja: 通常のテストはテストがコケても走り続ける
+---
+Makes no sense when a failure means you lose context
+# loc-ja: でも、コケたときにコンテキストが失われるようなら意味がないので
+---
+Every 'check' block aborts on failure
+# loc-ja: 'check'ブロックがコケたらテストを中断する
+---
+Abort means 'failing test'
+# loc-ja: もっとも、中断したからって「テストがコケた」ということにはならない
+---
+Every 'session' has a cookie jar and WWW::Mechanize
+# loc-ja: 'session'にはかならずクッキージャーと WWW::Mechanize が含まれている
+---
+#mode perl
+session "check logins" => run {
+    flow "basic connectivity" => check {
+        get 'http://fsck.com';
+        content should match qr{fsck.com};
+        click href qr{book};
+        content should match qr{RT Essentials}i;
+    };
+};
+---
+What's the weird syntax?
+# loc-ja: なに、この妙なシンタックス?
+---
+# mode perl
+content should match qr{RT Essentials}i;
+---
+#mode perl
+content should match qr{RT Essentials}i;
+
+#   vs
+
+ok($req->content =~ /RT Essentials/i);
+---
+# mode perl
+# How do we make this valid perl?
+# loc-ja: どうすればこれを正しいperlスクリプトにできるだろう
+
+content should match qr{RT Essentials}i;
+---
+Prototypes
+# loc-ja: プロトタイプだ
+---
+#mode perl
+sub match ($) {
+    return shift;
+}   
+---
+#mode perl
+sub should ($) {
+    my $item = shift;
+    return $item;
+}
+---
+#mode perl
+sub content ($) { 
+    my $regex = shift;
+    unless ( mech()->content =~ /$regex/ ) {
+        die "Content did not match $regex";
+    }
+}
+---
+#title Test::WWW::Declare - end
+# loc-ja: Test::WWW::Declare - おしまい
+That's Test::WWW::Declare
+# loc-ja: Test::WWW::Declare はこの辺で
+---
+#title Conclusion
+# loc-ja: 結論
+Creating DSLs is lots of fun
+# loc-ja: DSLをつくるのはとってもおもしろい
+---
+Creating DSLs can be a lot of work
+# loc-ja: DSLをつくるのはとっても大変なこともあるけど
+---
+Creating DSLs helps you learn Perl internals
+# loc-ja: DSLをつくるとPerlの内部の勉強になる
+---
+Creating DSLs helps find bugs in Perl
+# loc-ja: DSLをつくるとPerlのバグが見つかったりもする
+---
+DSLs can make coding more fun
+# loc-ja: DSLはコーディングをもっと楽しくする
+---
+Challenge: CPAN some Japanese DSLs
+# loc-ja: 宿題: CPANに日本語のDSLをアップしてくださいね
+---
+Thanks
+# loc-ja: ご静聴ありがとう
+---

Added: jifty/branches/virtual-models/doc/talks/yapc.asia.2007.txt
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/doc/talks/yapc.asia.2007.txt	Mon May  7 16:28:32 2007
@@ -0,0 +1,757 @@
+#title Jesse Vincent - Best Practical
+Domain Specific Languages in Perl
+---
+#title A bit about DSLs
+DSLs are little languages for specific programming tasks
+---
+DSLs are easier to read
+---
+DSLs are  more expressive
+---
+DSLs let you optimize your code for coding
+---
+Mostly, I'm going to talk about "Englishy" DSLs
+---
+Not all DSLs are Englishy
+---
+SQL
+---
+Regexes
+---
+Excel Macros
+---
+XML config files
+---
+XSL-T
+---
+GraphViz
+---
+...but I've been on an Englishy DSL kick
+---
+DSLs can be implemented in your 'host' language
+---
+(These get called "internal" DSLs)
+---
+DSLs can be implemented outside your 'host' langauge
+---
+(External DSLs)
+---
+Everything I'm going to talk about is Pure Perl (Internal)
+---
+The Ruby community is big on DSLs
+---
+You can make DSLs in Perl, too
+---
+(but it does take more work in Perl)
+---
+How did I get here?
+---
+#title How did I get here?
+Airplane
+---
+Narita Express
+---
+Subway
+---
+Ok, How'd I really get here?
+---
+All started at OSCON 2005
+---
+DHH demonstrated Rails migrations
+---
+They looked very sexy
+---
+I was very jealous
+---
+"You can't do this in any other language"
+---
+Never say that to a Perl Hacker
+---
+#title Agenda
+We've made some DSLs
+---
+One for declaring database schema
+---
+(I thought Rails did more. But I never read the manual)
+---
+(It does a lot more than Rails migrations)
+---
+One for web templating
+# loc-ja じゃあいったいどうして?!
+---
+(Yes, another web templating system)
+---
+(Hopefully, this one will provide some closure)
+---
+(You'll see)
+---
+One for making web testing easier
+---
+(It's VERY beta)
+---
+(Perfect for Web 2.0)
+---
+#title
+Jifty::DBI::Schema
+---
+#title Jifty::DBI::Schema - The design process
+Delarative Syntax for an Object Relational Mapper
+---
+Started sketching Jifty::DBI columns
+---
+Started with DBIx::SearchBuilder
+---
+Columns were defined as a hash
+---
+Hashes are ugly
+---
+We spent about a month playing with syntax.
+---
+Our first goal was "feels right"
+---
+Our second goal was "we can implement this"
+---
+I'm going to show you some of our design process
+---
+(It's a mix of code and IRC)
+---
+#mode perl
+$x = Jifty::DBI::SchemaBuilder->new;
+$x->define_blablalb
+$x->bla bla
+---
+#mode perl
+our db_table 'addresses';
+our field name => { 
+	has_type 'varchar'; 
+	has_default 'frank' 
+};
+---
+<chmrr> (by the way, i'm pretty sure we don't get to do the sub-at-the-end thing either... I tried lots of hacky ways to get it working and failed.)
+
+<glasser> yeah, I think we're going to end up having a pseudo-sub that's really a hash behind the scenes 
+---
+#mode perl
+{
+    my $s = Jifty::DBI::SG->import_functions;
+    
+    db_table bla bla bla;
+    field bla;
+    field bar;
+} # $s.DESTROY gets called and unimports db_table/field/...
+---
+(This was astonishingly close to what we do today.)
+---
+#mode perl
+my $schema = Jifty::DBI::RecordSchema->new;
+$schema->for_class(__PACKAGE__);
+
+$schema->field name => { 
+	has_type 'varchar'; 
+	has_default 'Frank'
+}
+
+---
+#mode perl
+
+BEGIN { @ISA = 'Jifty::DBI::Record' }
+use Jifty::DBI::Record; # but this sucks!
+
+use base qw/Jifty::DBI::Record/;
+
+__PACKAGE__->schema_version (0.0001) 
+# (or some other method that does two thing evily).
+---
+<obra> we could tie @ISA
+
+<obra> ...I'm kidding
+---
+<obra> we could tie the symbol table
+
+<obra> ...It just doesn't work
+---
+#mode perl
+use base 'Jifty::DBI::Record';
+Jifty::DBI::Record->___from_code();
+
+db_table 'addresses';
+
+field {
+    called 'name'; # ? 
+}
+--- 
+<glasser> is 
+	
+  "has_type 'string'" 
+
+definitely better than 
+
+  "type => 'string'"  
+
+in your book?
+---
+<obra> how would you do: 
+
+ refers_to_many RT::Tickets by 'owner';
+
+<Robrt> hmm. i thought about this before.  we can do like simon and
+
+ refers_to_many "RT::Tickets by owner";
+
+<Robrt> but I don't really like that.  parsing is lame.
+
+<Robrt> I'm *pretty* sure that we can't get the line you've written to compile.
+---
+<obra> I've got a bad perl5 idea for you. Robert claims it's impossible
+
+<obra> I'm trying to make the syntax "refers_to_many 'BTDT::Model::Tasks' by 'owner';" valid perl5 syntax.
+---
+<audreyt> well, that may be true but you don't want that.
+
+<audreyt> refers_to_many BTDT::Model::Tasks by 'owner'
+
+<audreyt> is more readable and easily implemented.
+
+<audreyt> sub by ($) { by => @_ }
+
+<audreyt> done!
+
+<audreyt> stop thinking classes as strings :)
+---
+<obra> shit! it actually works!
+---
+What we had left:
+---
+the "field foo => sub {};" issue
+--- 
+#mode perl
+
+ # We wanted something that acted like this
+ # But without the ugly 'sub' keyword
+ field email => sub {
+ 
+    has_type 'varchar';
+    has_default 'Frank';
+};
+
+---
+#mode perl
+# We cculd do this, but it used a hash
+# not a block
+
+field phone => {
+    has_type 'varchar';
+};
+
+field employee_id => {
+    refers_to_a Sample::Employee;
+}
+---
+#mode perl
+
+# This is ugly and verbose
+
+package Sample::Employee;
+
+use base qw/Jifty::DBI::Record/;
+
+__PACKAGE__->db_table 'employees';
+
+__PACKAGE__->field name => has_type 'varchar';
+
+__PACKAGE__->field dexterity =>  { has_type 'integer'};
+
+---
+#title In the end...
+We ended up with Jifty::DBI columns
+---
+#mode perl
+use Jifty::DBI::Record schema {
+column auth_token => type is 'text',
+  render as 'Unrendered';
+
+column score => type is 'int',
+  is immutable,
+  label is 'Score';
+
+column time_zone =>
+  label is 'Time zone',
+  since '0.0.12',
+  default is 'America/New_York',
+  valid are formatted_timezones();
+};
+---
+We implemented the DSL twice
+---
+#title 
+Take 1
+---
+#title Take 1
+Jifty::DBI::Schema
+---
+#title Take 1: Jifty::DBI::Schema
+Our first DSL in Perl
+---
+We beat the parser into submission with a few tricks
+---
+Injection of functions
+---
+We saw that a moment ago
+---
+Clever function prototypes
+---
+Let's have a look at that
+---
+#mode perl
+# The syntax we wanted
+
+score => type is 'int',
+  is immutable,
+  default is '0',
+  render as 'text',
+  label is 'Score',
+  since is '0.0.7';
+---
+#mode perl
+# perl -MO=Deparse parses that as:
+
+'is'->type('int', 
+  'immutable'->is, 
+   'is'->default('0', 
+      'as'->render('text', 
+        'is'->label('Score', 
+          'is'->since('0.0.7')))));
+---
+How can we fix that?
+---
+Prototype hacking!
+---
+#mode perl
+sub is ($) { return shift };
+sub as ($) { return shift };
+sub since ($) { }
+sub type ($) { }
+sub render ($) {}
+sub label ($) {}
+sub default ($) {}
+---
+#mode perl
+
+# Now, perl -MO=Deparse parses that as:
+
+ type(is('int')), 
+ is('immutable'), 
+ default(is('0')), 
+ render(as('text')), 
+ label(is('Score')), 
+ since(is('0.0.7'));
+---
+Downsides
+---
+Limited flexibility
+---
+Needs new functions for every attribute
+---
+#title Take 2
+#`mpg123  ~/katamari.mp3`
+Object::Declare
+---
+#title Take 2: Object::Declare
+Katamari for Code
+---
+#mode perl
+use Jifty::DBI::Record schema { 
+
+ column score => type is 'int',
+  is immutable,
+  render as 'text',
+  default is '0',
+  label is 'Score',
+  since is '0.0.7';
+};
+---
+# mode perl
+# perl -MO=Deparse parses that as:
+
+'is'->type('int', 
+  'immutable'->is, 
+   'is'->default('0', 
+      'as'->render('text', 
+	'is'->label('Score', 
+	  'is'->since('0.0.7')))));
+---
+Why fight the parser?
+---
+Perl gives us all the rope we need
+---
+UNIVERSAL:: and ::AUTOLOAD
+---
+What actually happens at compile time:
+
+---
+The 'schema' function in our baseclass takes a code block
+---
+...and returns a closure
+---
+Jifty::DBI::Record::import takes over:
+---
+it takes the closure
+---
+it installs some methods...
+---
+...is::AUTOLOAD and UNIVERSAL::is and as::AUTOLOAD
+---
+it runs the closure
+---
+it hands the result off to a method of your choice
+---
+it removes its magic symbols
+---
+...and then your program gets control back
+---
+#title Jifty::DBI::Schema - end
+That's Jifty::DBI::Schema.
+---
+#title
+Template::Declare
+---
+#title Template::Declare
+A pure Perl Templating Language
+---
+What it looks like
+---
+#mode perl
+template '/pages/mypage.html' => sub {
+    html {
+        head {};
+        body {
+            h1 {'Hey, this is text'};
+            }
+        }
+};
+---
+#mode perl
+template choices => page {
+    h1 { 'My Choices' }
+    dl {
+        my $choices = Doxory::Model::ChoiceCollection->new;
+        $choices->limit(
+            column => 'asked_by',
+            value  => Jifty->web->current_user->id,
+        );
+        while (my $c = $choices->next) {
+            dt { $c->name, ' (', $c->asked_by->name, ')' }
+            dd { b { $c->a } em { 'vs' } b { $c->b } }
+        }
+    }
+};
+---
+But! 
+---
+Content! Templates! 
+---
+Design! Code!
+---
+OMGWTF!? THAT'S WRONG!
+---
+The person who told you it's wrong was lying to you.
+---
+We're Perl hackers
+---
+Why are we writing our templates in another language?
+---
+This is not 1997
+---
+It's 2007
+---
+People use CSS for design now
+---
+Programmers still have to make templates
+---
+Templates run like CODE
+---
+Because they ARE code
+---
+Let's use our CODING tools to work with them
+---
+#mode perl
+#title Refactoring
+
+template 'mypage.html' => page {
+ h1 { 'Two choices' };
+ div { attr { class => 'item' };
+       h2 { 'Item 1'};
+  };
+ div { attr { class => 'item' };
+       h2 { 'Item 2'};
+  };
+}; 
+---
+#title Refactoring
+#mode perl
+
+template 'mypage.html' => page {
+ h1 { 'Two choices' };
+ for ("Item 1", "Item 2") { item($_); }
+};
+
+sub item {
+    my $content = shift;
+    div {
+        attr { class => 'item' };
+        h2 {$content};
+    };
+
+}
+---
+We can refactor templates!
+---
+Have you ever tried to refactor HTML?
+---
+Our HTML is magically valid
+---
+(Syntax errors are...Syntax Errors)
+---
+#title Stashing our templates
+#mode perl
+template '/foo/index.html' => sub {... };
+---
+'sub template' takes a name and a coderef
+---
+But where do we put these?
+---
+We need a global stash
+---
+It needs to be per package 
+(Don't want to mix things together)
+---
+Basically, we need a symbol table
+---
+It's Perl
+---
+We have THE symbol table
+---
+But URLs have characters that are illegal in sub names. :/
+---
+Actually, Perl doesn't care
+---
+#mode perl
+no strict 'refs';
+*{ $class . '::' . $subname } = $coderef;
+---
+That just works.
+---
+Even if your sub is named './\\foo#title <>'
+---
+But how do you call it?
+---
+#mode perl
+# perldoc UNIVERSAL
+---
+CLASS->can( METHOD )
+"can" checks if the object or class has a method called "METHOD".
+If it does then a reference to the sub is returned.
+---
+#title Closures
+Now, about that syntax.
+---
+HTML tags take blocks of content
+---
+Our tag methods take blocks of Perl
+---
+They return closures when you want them to
+---
+They run and output their content when you want them to
+---
+#mode perl
+sub h1 (&;$) {
+  my $code = shift;
+  
+  ...
+
+  if (defined wantarray) {
+    return sub { ...closure around $code...};
+  } else {
+    # Actually do our work, run $code and return the output
+    return $code->();
+  }
+}
+---
+We install methods for every HTML tag
+---
+(Except 'tr'. Anybody know why?)
+---
+#mode perl
+use CGI ();
+install_tag($_) 
+  for ( @CGI::EXPORT_TAGS{
+	qw/:html2 :html3 :html4 
+	   :netscape :form/}
+);
+---
+#title Not everything is roses
+(Here's where it all goes wrong)
+---
+HTML Attributes
+---
+# mode perl
+# What we've got:
+
+div { attr { id => 'my-div'};
+      ...
+};
+
+# and
+
+with ( id => 'my-div'), div {
+...
+};
+---
+# mode perl
+# What I think I'd like:
+
+div ( id => 'my-div' ), { 
+... 
+}
+---
+So, what's the big problem?
+---
+Just change the prototype
+---
+In Perl, the (&) in a prototype MUST come first
+---
+ORZ
+---
+Can anybody help me?
+---
+#title Template::Declare - end
+That's Template::Declare
+---
+#title 
+Test::WWW::Declare
+---
+#title Test::WWW::Declare
+A language for testing web applications
+---
+In early development
+---
+It might change
+---
+Web test scripts are UGLY
+---
+Test::WWW::Declare is PRETTY
+---
+Simple, declarative web testing
+---
+Easy to read
+---
+Easy to write
+---
+Looks more like what users do
+---
+#mode perl
+# Test::WWW::Mechanize
+
+my $server=Jifty::Test->make_server;
+isa_ok($server, 'Jifty::Server');
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new;
+$mech->get_html_ok($URL);
+like($mech->uri, qr{splash}, 
+     'Redirected to splash page');
+---
+The insides are great
+---
+The syntax ain't
+---
+We built on Test::More and WWW::Mechanize
+---
+#mode perl
+
+# Test::WWW::Declare
+
+session "search" => run {
+    flow "google searches work" => check {
+        get 'http://google.com/ncr'; 
+        fill form 'f' => { 
+		q   => 'Squeamish ossifrage' };
+        click button 'Google Search';
+    }
+};
+---
+Regular tests keep running on failure
+---
+Makes no sense when a failure means you lose context
+---
+Every 'check' block aborts on failure
+---
+Abort means 'failing test'
+---
+Every 'session' has a cookie jar and WWW::Mechanize
+---
+#mode perl
+session "check logins" => run {
+    flow "basic connectivity" => check {
+        get 'http://fsck.com';
+        content should match qr{fsck.com};
+        click href qr{book};
+        content should match qr{RT Essentials}i;
+    };
+};
+---
+What's the weird syntax?
+---
+# mode perl
+content should match qr{RT Essentials}i;
+---
+#mode perl
+content should match qr{RT Essentials}i;
+
+#   vs
+
+ok($req->content =~ /RT Essentials/i);
+---
+# mode perl
+# How do we make this valid perl?
+
+content should match qr{RT Essentials}i;
+---
+Prototypes
+---
+#mode perl
+sub match ($) {
+    return shift;
+}   
+---
+#mode perl
+sub should ($) {
+    my $item = shift;
+    return $item;
+}
+---
+#mode perl
+sub content ($) { 
+    my $regex = shift;
+    unless ( mech()->content =~ /$regex/ ) {
+        die "Content did not match $regex";
+    }
+}
+---
+#title Test::WWW::Declare - end
+That's Test::WWW::Declare
+---
+#title Conclusion
+Creating DSLs is lots of fun
+---
+Creating DSLs can be a lot of work
+---
+Creating DSLs helps you learn Perl internals
+---
+Creating DSLs helps find bugs in Perl
+---
+DSLs can make coding more fun
+---
+Challenge: CPAN some Japanese DSLs
+---
+Thanks
+---

Added: jifty/branches/virtual-models/doc/talks/yapcasia2007-doxory.key.tbz2
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/doc/talks/yapcasia2007-doxory.pdf
==============================================================================
Binary files (empty file) and jifty/branches/virtual-models/doc/talks/yapcasia2007-doxory.pdf	Mon May  7 16:28:32 2007 differ

Added: jifty/branches/virtual-models/examples/Doxory/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/Makefile.PL	Mon May  7 16:28:32 2007
@@ -0,0 +1,8 @@
+use inc::Module::Install;
+
+name        'Doxory';
+version     '0.01';
+requires    'Jifty' => '0.70117';
+requires    'Regexp::Common::profanity_us';
+
+WriteAll;

Added: jifty/branches/virtual-models/examples/Doxory/bin/jifty
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/bin/jifty	Mon May  7 16:28:32 2007
@@ -0,0 +1,15 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use File::Basename qw(dirname); 
+use UNIVERSAL::require;
+
+BEGIN {
+    Jifty::Util->require or die $UNIVERSAL::require::ERROR;
+    my $root = Jifty::Util->app_root;
+    unshift @INC, "$root/lib" if ($root);
+}
+
+use Jifty::Script;
+local $SIG{INT} = sub { warn "Stopped\n"; exit; };
+Jifty::Script->dispatch();

Added: jifty/branches/virtual-models/examples/Doxory/doxory
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/examples/Doxory/etc/config.yml
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/etc/config.yml	Mon May  7 16:28:32 2007
@@ -0,0 +1,50 @@
+--- 
+framework: 
+  SkipAccessControl: 1
+  AdminMode: 1
+  ApplicationClass: Doxory
+  ApplicationName: Doxory
+  ApplicationUUID: 181049AC-E029-11DB-A5EB-227D19064FA1
+  Database: 
+    CheckSchema: 1
+    Database: doxory
+    Driver: SQLite
+    Host: localhost
+    Password: ''
+    RecordBaseClass: Jifty::DBI::Record::Cachable
+    User: ''
+    Version: 0.0.1
+  DevelMode: 1
+  L10N: 
+    PoDir: share/po
+  LogLevel: INFO
+  Mailer: Sendmail
+  MailerArgs: []
+
+  Plugins: 
+    - SkeletonApp: {}
+    - REST: {}
+    - Halo: {}
+    - ErrorTemplates: {}
+    - CompressedCSSandJS: {}
+    - Authentication::Password: {}
+
+  PubSub: 
+    Backend: Memcached
+    Enable: ~
+  TemplateClass: Doxory::View
+  SkipAccessControl: 1
+  Web: 
+    BaseURL: http://localhost
+    DataDir: var/mason
+    Globals: []
+
+    MasonConfig: 
+      autoflush: 0
+      default_escape_flags: h
+      error_format: text
+      error_mode: fatal
+    Port: 8888
+    ServeStaticFiles: 1
+    StaticRoot: share/web/static
+    TemplateRoot: share/web/templates

Added: jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,43 @@
+package Doxory::Dispatcher;
+use strict;
+use warnings;
+use Jifty::Dispatcher -base;
+
+before '*' => run {
+    if (Jifty->web->current_user->id) {
+        my $top = Jifty->web->navigation;
+        $top->child( _('Pick!')    => url => '/pick' );
+        $top->child( _('Choices')  => url => '/choices' );
+    }
+    elsif ($1 !~ /^login|^signup/) {
+        tangent 'login';
+    }
+};
+
+#on '/' => show 'new_choice';
+
+on pick => run {
+    my $choices = Doxory::Model::ChoiceCollection->new;
+    my $votes   = $choices->join(
+        type    => 'left',
+        alias1  => 'main',  column1 => 'id',
+        table2  => 'votes', column2 => 'choice',
+    );
+    $choices->limit(
+        leftjoin => $votes, column => 'voter',
+        value    => Jifty->web->current_user->id,
+    );
+    $choices->limit(
+        alias    => $votes, column => 'voter',
+        operator => 'IS',   value => 'NULL',
+    );
+
+    if (my $c = $choices->first) {
+        set choice => $c;
+    }
+    else {
+        show 'nothing_to_pick';
+    }
+};
+
+1;

Added: jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/Choice.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/Choice.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,64 @@
+use strict;
+use warnings;
+
+package Doxory::Model::Choice;
+use Jifty::DBI::Schema;
+
+use Doxory::Record schema {
+    column name =>
+        label is _('I need help deciding...'),
+        render as 'textarea';
+
+    column a =>
+        label is _('On the one hand'),
+        render as 'textarea',
+        is mandatory;
+
+    column b =>
+        label is _('On the other hand'),
+        render as 'textarea',
+        is mandatory;
+
+    column asked_by =>
+        label is _('Asked by'),
+        default is defer { Jifty->web->current_user->id },
+        references Doxory::Model::User;
+};
+use Regexp::Common 'profanity_us';
+
+sub validate_name {
+    my ($self, $name) = @_;
+    if ($name =~ /$RE{profanity}/i) {
+        return (0, 'Would you speak like that in front of your mother? *cough*');
+    }
+    return 1;
+}
+
+sub canonicalize_name {
+    my ($self, $name) = @_;
+
+    $name =~ s/$RE{profanity}/**expletives**/gi;
+    return $name;
+}
+
+sub in_favor_of_a {
+    my $self = shift;
+    $self->in_favor_of('a');
+}
+
+sub in_favor_of_b {
+    my $self = shift;
+    $self->in_favor_of('b');
+}
+
+sub in_favor_of {
+    my $self = shift;
+    my $suggestion = shift;
+    my $votes = Doxory::Model::VoteCollection->new();
+    Carp::cluck unless ($self->id);
+    $votes->limit(column => 'choice', value => $self->id);
+    $votes->limit(column => 'suggestion' => value => $suggestion);
+    return $votes;
+}
+
+1;

Added: jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/User.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/User.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+
+package Doxory::Model::User;
+use Jifty::DBI::Schema;
+
+use Doxory::Record schema {
+
+column name =>
+    label is 'Username',
+    hints is 'Other people see this when you ask questions.',
+    is distinct, is mandatory;
+
+column email =>
+    label is 'Email',
+    hints is 'We will not sell it to anybody. Honest.',
+    default is '',
+    is distinct, is immutable;
+
+};
+
+use Jifty::Plugin::User::Mixin::Model::User;
+use Jifty::Plugin::Authentication::Password::Mixin::Model::User;
+
+# Your model-specific methods go here.
+1;
+

Added: jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/Vote.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/lib/Doxory/Model/Vote.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+
+package Doxory::Model::Vote;
+use Jifty::DBI::Schema;
+
+use Doxory::Record schema {
+    column choice =>
+        references Doxory::Model::Choice;
+
+    column voter =>
+        references Doxory::Model::User;
+
+    column suggestion =>
+        valid are qw( a b skip );
+
+    column comments =>
+        label is _('Comments?'),
+        render as 'textarea';
+};
+
+1;

Added: jifty/branches/virtual-models/examples/Doxory/lib/Doxory/View.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/lib/Doxory/View.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,84 @@
+package Doxory::View;
+use utf8;
+use strict;
+use warnings;
+use Jifty::View::Declare -base;
+
+template '/' => page {
+    h1 { _('Ask a question!') }
+    div { show 'new_choice' }
+};
+
+private template new_choice => sub {
+    form {
+        my $action = new_action( class => 'CreateChoice' );
+        render_action( $action => ['name', 'a', 'b'] );
+        form_submit( label => _('Ask the crowd!') );
+    }
+};
+
+template choices => page {
+    h1 { 'My Choices' }
+    dl {
+        my $choices = Doxory::Model::ChoiceCollection->new;
+        $choices->limit(
+            column  => 'asked_by',
+            value   => Jifty->web->current_user->id,
+        );
+        while (my $c = $choices->next) {
+            dt { $c->name, ' (', $c->asked_by->name, ')' }
+            dd { 
+            b { $c->a, ' (', $c->in_favor_of_a->count, ')' }
+            em { 'vs' }
+            b { $c->b, ' (', $c->in_favor_of_b->count, ')' }
+            }
+        }
+    }
+};
+
+template pick => page {
+    my $choice = get('choice');
+    my $action = new_action( class => 'CreateVote' );
+    my $redir  = new_action(
+        class     => "Jifty::Action::Redirect",
+        arguments => { url => '/pick' },
+    );
+    # XXX - For some reason passing it in on the previous line doesn't work.
+    my %args   = (
+        choice => $choice->id,
+        voter  => Jifty->web->current_user->id,
+    );
+
+    h1 { $choice->asked_by->name, ': ', $choice->name }
+    div { form {
+        my ($x, $y) = map { $action->button(
+            submit      => [ $action, $redir ],
+            label       => $choice->$_,
+            arguments   => { suggestion => $_, %args },
+        ) } ((rand > 0.5) ? ('a', 'b') : ('b', 'a'));
+
+        span { $x } em { 'or' } span { $y } em { 'or' } span {
+            $action->button(
+                submit      => [ $action, $redir ],
+                label       => 'None of the above',
+                arguments   => { suggestion => 'skip', %args },
+            );
+        }
+
+        p { render_param( $action => 'comments' ) }
+    } }
+};
+
+template nothing_to_pick => page {
+    h1 { "There's nothing for you to pick." }
+
+    p { "No one you know is angsting about anything. Everybody knows where
+         they're going to dinner, what to do on their next date and whether to
+         drop that class. You have such lovely and well adjusted friends." }
+
+    h2 { "Maybe it's time to ask for some advice..." };
+
+    show 'new_choice';
+};
+
+1;

Added: jifty/branches/virtual-models/examples/Doxory/share/po/zh_cn.po
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/share/po/zh_cn.po	Mon May  7 16:28:32 2007
@@ -0,0 +1,55 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: lib/Doxory/View.pm:8
+msgid "Ask a question!"
+msgstr "我有问题!"
+
+#: lib/Doxory/View.pm:16
+msgid "Ask the crowd!"
+msgstr "听听乡民怎么说!"
+
+#: lib/Doxory/Model/Choice.pm:23
+msgid "Asked by"
+msgstr "提问人"
+
+#: lib/Doxory/Dispatcher.pm:10
+msgid "Choices"
+msgstr "开票纪录"
+
+#: lib/Doxory/Model/Vote.pm:18
+msgid "Comments?"
+msgstr "有何指教?"
+
+#: lib/Doxory/Model/Choice.pm:9
+msgid "I need help deciding..."
+msgstr "帮帮我, 该怎么办..."
+
+#: lib/Doxory/Model/Choice.pm:13
+msgid "On the one hand"
+msgstr "我应该...?"
+
+#: lib/Doxory/Model/Choice.pm:18
+msgid "On the other hand"
+msgstr "或者...?"
+
+#: lib/Doxory/Dispatcher.pm:9
+msgid "Pick!"
+msgstr "投票!"
+
+msgid "Logout"
+msgstr "注销"

Added: jifty/branches/virtual-models/examples/Doxory/share/po/zh_tw.po
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/share/po/zh_tw.po	Mon May  7 16:28:32 2007
@@ -0,0 +1,55 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: lib/Doxory/View.pm:8
+msgid "Ask a question!"
+msgstr "我有問題!"
+
+#: lib/Doxory/View.pm:16
+msgid "Ask the crowd!"
+msgstr "聽聽鄉民怎麼說!"
+
+#: lib/Doxory/Model/Choice.pm:23
+msgid "Asked by"
+msgstr "提問人"
+
+#: lib/Doxory/Dispatcher.pm:10
+msgid "Choices"
+msgstr "開票紀錄"
+
+#: lib/Doxory/Model/Vote.pm:18
+msgid "Comments?"
+msgstr "有何指教?"
+
+#: lib/Doxory/Model/Choice.pm:9
+msgid "I need help deciding..."
+msgstr "幫幫我, 該怎麼辦..."
+
+#: lib/Doxory/Model/Choice.pm:13
+msgid "On the one hand"
+msgstr "我應該...?"
+
+#: lib/Doxory/Model/Choice.pm:18
+msgid "On the other hand"
+msgstr "或者...?"
+
+#: lib/Doxory/Dispatcher.pm:9
+msgid "Pick!"
+msgstr "投票!"
+
+msgid "Logout"
+msgstr "登出"

Added: jifty/branches/virtual-models/examples/Doxory/t/00-model-User.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Doxory/t/00-model-User.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+=head1 DESCRIPTION
+
+A basic test harness for the User model.
+
+=cut
+
+use Jifty::Test tests => 11;
+
+# Make sure we can load the model
+use_ok('Doxory::Model::User');
+
+# Grab a system user
+my $system_user = Doxory::CurrentUser->superuser;
+ok($system_user, "Found a system user");
+
+# Try testing a create
+my $o = Doxory::Model::User->new(current_user => $system_user);
+my ($id) = $o->create();
+ok($id, "User create returned success");
+ok($o->id, "New User has valid id set");
+is($o->id, $id, "Create returned the right id");
+
+# And another
+$o->create();
+ok($o->id, "User create returned another value");
+isnt($o->id, $id, "And it is different from the previous one");
+
+# Searches in general
+my $collection =  Doxory::Model::UserCollection->new(current_user => $system_user);
+$collection->unlimit;
+is($collection->count, 2, "Finds two records");
+
+# Searches in specific
+$collection->limit(column => 'id', value => $o->id);
+is($collection->count, 1, "Finds one record with specific id");
+
+# Delete one of them
+$o->delete;
+$collection->redo_search;
+is($collection->count, 0, "Deleted row is gone");
+
+# And the other one is still there
+$collection->unlimit;
+is($collection->count, 1, "Still one left");
+

Added: jifty/branches/virtual-models/examples/Example-Todo/META.yml
==============================================================================

Added: jifty/branches/virtual-models/examples/Example-Todo/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/Makefile.PL	Mon May  7 16:28:32 2007
@@ -0,0 +1,7 @@
+use inc::Module::Install;
+
+name        'Example::Todo';
+version     '0.01';
+requires    'Jifty' => '0.70117';
+
+WriteAll;

Added: jifty/branches/virtual-models/examples/Example-Todo/bin/jifty
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/bin/jifty	Mon May  7 16:28:32 2007
@@ -0,0 +1,15 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use File::Basename qw(dirname); 
+use UNIVERSAL::require;
+
+BEGIN {
+    Jifty::Util->require or die $UNIVERSAL::require::ERROR;
+    my $root = Jifty::Util->app_root;
+    unshift @INC, "$root/lib" if ($root);
+}
+
+use Jifty::Script;
+local $SIG{INT} = sub { warn "Stopped\n"; exit; };
+Jifty::Script->dispatch();

Added: jifty/branches/virtual-models/examples/Example-Todo/etc/config.yml
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/etc/config.yml	Mon May  7 16:28:32 2007
@@ -0,0 +1,62 @@
+--- 
+framework: 
+  AdminMode: 1
+  ApplicationClass: Example::Todo
+  ApplicationName: Example-Todo
+  ApplicationUUID: 80DF397A-D999-11DB-B80A-9318EBB6763A
+  Database: 
+    CheckSchema: 1
+    Database: example_todo
+    Driver: SQLite
+    Host: localhost
+    Password: ''
+    RecordBaseClass: Jifty::DBI::Record::Cachable
+    User: ''
+    Version: 0.0.1
+  DevelMode: 1
+  L10N: 
+    PoDir: share/po
+  LogLevel: INFO
+  Mailer: Sendmail
+  MailerArgs: []
+
+  Plugins: 
+    - 
+      SkeletonApp: {}
+
+    - 
+      REST: {}
+
+    - 
+      Halo: {}
+
+    - 
+      ErrorTemplates: {}
+
+    - 
+      OnlineDocs: {}
+
+    - 
+      CompressedCSSandJS: {}
+
+    - 
+      AdminUI: {}
+
+  PubSub: 
+    Backend: Memcached
+    Enable: ~
+  TemplateClass: Example::Todo::View
+  Web: 
+    BaseURL: http://localhost
+    DataDir: var/mason
+    Globals: []
+
+    MasonConfig: 
+      autoflush: 0
+      default_escape_flags: h
+      error_format: text
+      error_mode: fatal
+    Port: 8888
+    ServeStaticFiles: 1
+    StaticRoot: share/web/static
+    TemplateRoot: share/web/templates

Added: jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,281 @@
+#line 1
+package Module::Install;
+
+# For any maintainers:
+# The load order for Module::Install is a bit magic.
+# It goes something like this...
+#
+# IF ( host has Module::Install installed, creating author mode ) {
+#     1. Makefile.PL calls "use inc::Module::Install"
+#     2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
+#     3. The installed version of inc::Module::Install loads
+#     4. inc::Module::Install calls "require Module::Install"
+#     5. The ./inc/ version of Module::Install loads
+# } ELSE {
+#     1. Makefile.PL calls "use inc::Module::Install"
+#     2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
+#     3. The ./inc/ version of Module::Install loads
+# }
+
+use 5.004;
+use strict 'vars';
+
+use vars qw{$VERSION};
+BEGIN {
+    # All Module::Install core packages now require synchronised versions.
+    # This will be used to ensure we don't accidentally load old or
+    # different versions of modules.
+    # This is not enforced yet, but will be some time in the next few
+    # releases once we can make sure it won't clash with custom
+    # Module::Install extensions.
+    $VERSION = '0.64';
+}
+
+# Whether or not inc::Module::Install is actually loaded, the
+# $INC{inc/Module/Install.pm} is what will still get set as long as
+# the caller loaded module this in the documented manner.
+# If not set, the caller may NOT have loaded the bundled version, and thus
+# they may not have a MI version that works with the Makefile.PL. This would
+# result in false errors or unexpected behaviour. And we don't want that.
+my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
+unless ( $INC{$file} ) {
+    die <<"END_DIE";
+Please invoke ${\__PACKAGE__} with:
+
+    use inc::${\__PACKAGE__};
+
+not:
+
+    use ${\__PACKAGE__};
+
+END_DIE
+}
+
+# If the script that is loading Module::Install is from the future,
+# then make will detect this and cause it to re-run over and over
+# again. This is bad. Rather than taking action to touch it (which
+# is unreliable on some platforms and requires write permissions)
+# for now we should catch this and refuse to run.
+if ( -f $0 and (stat($0))[9] > time ) {
+	die << "END_DIE";
+Your installer $0 has a modification time in the future.
+
+This is known to create infinite loops in make.
+
+Please correct this, then run $0 again.
+
+END_DIE
+}
+
+use Cwd        ();
+use File::Find ();
+use File::Path ();
+use FindBin;
+
+*inc::Module::Install::VERSION = *VERSION;
+ at inc::Module::Install::ISA     = __PACKAGE__;
+
+sub autoload {
+    my $self = shift;
+    my $who  = $self->_caller;
+    my $cwd  = Cwd::cwd();
+    my $sym  = "${who}::AUTOLOAD";
+    $sym->{$cwd} = sub {
+        my $pwd = Cwd::cwd();
+        if ( my $code = $sym->{$pwd} ) {
+            # delegate back to parent dirs
+            goto &$code unless $cwd eq $pwd;
+        }
+        $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
+        unshift @_, ($self, $1);
+        goto &{$self->can('call')} unless uc($1) eq $1;
+    };
+}
+
+sub import {
+    my $class = shift;
+    my $self  = $class->new(@_);
+    my $who   = $self->_caller;
+
+    unless ( -f $self->{file} ) {
+        require "$self->{path}/$self->{dispatch}.pm";
+        File::Path::mkpath("$self->{prefix}/$self->{author}");
+        $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
+        $self->{admin}->init;
+        @_ = ($class, _self => $self);
+        goto &{"$self->{name}::import"};
+    }
+
+    *{"${who}::AUTOLOAD"} = $self->autoload;
+    $self->preload;
+
+    # Unregister loader and worker packages so subdirs can use them again
+    delete $INC{"$self->{file}"};
+    delete $INC{"$self->{path}.pm"};
+}
+
+sub preload {
+    my ($self) = @_;
+
+    unless ( $self->{extensions} ) {
+        $self->load_extensions(
+            "$self->{prefix}/$self->{path}", $self
+        );
+    }
+
+    my @exts = @{$self->{extensions}};
+    unless ( @exts ) {
+        my $admin = $self->{admin};
+        @exts = $admin->load_all_extensions;
+    }
+
+    my %seen;
+    foreach my $obj ( @exts ) {
+        while (my ($method, $glob) = each %{ref($obj) . '::'}) {
+            next unless $obj->can($method);
+            next if $method =~ /^_/;
+            next if $method eq uc($method);
+            $seen{$method}++;
+        }
+    }
+
+    my $who = $self->_caller;
+    foreach my $name ( sort keys %seen ) {
+        *{"${who}::$name"} = sub {
+            ${"${who}::AUTOLOAD"} = "${who}::$name";
+            goto &{"${who}::AUTOLOAD"};
+        };
+    }
+}
+
+sub new {
+    my ($class, %args) = @_;
+
+    # ignore the prefix on extension modules built from top level.
+    my $base_path = Cwd::abs_path($FindBin::Bin);
+    unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
+        delete $args{prefix};
+    }
+
+    return $args{_self} if $args{_self};
+
+    $args{dispatch} ||= 'Admin';
+    $args{prefix}   ||= 'inc';
+    $args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
+    $args{bundle}   ||= 'inc/BUNDLES';
+    $args{base}     ||= $base_path;
+    $class =~ s/^\Q$args{prefix}\E:://;
+    $args{name}     ||= $class;
+    $args{version}  ||= $class->VERSION;
+    unless ( $args{path} ) {
+        $args{path}  = $args{name};
+        $args{path}  =~ s!::!/!g;
+    }
+    $args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
+
+    bless( \%args, $class );
+}
+
+sub call {
+	my ($self, $method) = @_;
+	my $obj = $self->load($method) or return;
+        splice(@_, 0, 2, $obj);
+	goto &{$obj->can($method)};
+}
+
+sub load {
+    my ($self, $method) = @_;
+
+    $self->load_extensions(
+        "$self->{prefix}/$self->{path}", $self
+    ) unless $self->{extensions};
+
+    foreach my $obj (@{$self->{extensions}}) {
+        return $obj if $obj->can($method);
+    }
+
+    my $admin = $self->{admin} or die <<"END_DIE";
+The '$method' method does not exist in the '$self->{prefix}' path!
+Please remove the '$self->{prefix}' directory and run $0 again to load it.
+END_DIE
+
+    my $obj = $admin->load($method, 1);
+    push @{$self->{extensions}}, $obj;
+
+    $obj;
+}
+
+sub load_extensions {
+    my ($self, $path, $top) = @_;
+
+    unless ( grep { lc $_ eq lc $self->{prefix} } @INC ) {
+        unshift @INC, $self->{prefix};
+    }
+
+    foreach my $rv ( $self->find_extensions($path) ) {
+        my ($file, $pkg) = @{$rv};
+        next if $self->{pathnames}{$pkg};
+
+        local $@;
+        my $new = eval { require $file; $pkg->can('new') };
+        unless ( $new ) {
+            warn $@ if $@;
+            next;
+        }
+        $self->{pathnames}{$pkg} = delete $INC{$file};
+        push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
+    }
+
+    $self->{extensions} ||= [];
+}
+
+sub find_extensions {
+    my ($self, $path) = @_;
+
+    my @found;
+    File::Find::find( sub {
+        my $file = $File::Find::name;
+        return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
+        my $subpath = $1;
+        return if lc($subpath) eq lc($self->{dispatch});
+
+        $file = "$self->{path}/$subpath.pm";
+        my $pkg = "$self->{name}::$subpath";
+        $pkg =~ s!/!::!g;
+
+        # If we have a mixed-case package name, assume case has been preserved
+        # correctly.  Otherwise, root through the file to locate the case-preserved
+        # version of the package name.
+        if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
+            open PKGFILE, "<$subpath.pm" or die "find_extensions: Can't open $subpath.pm: $!";
+            my $in_pod = 0;
+            while ( <PKGFILE> ) {
+                $in_pod = 1 if /^=\w/;
+                $in_pod = 0 if /^=cut/;
+                next if ($in_pod || /^=cut/);  # skip pod text
+                next if /^\s*#/;               # and comments
+                if ( m/^\s*package\s+($pkg)\s*;/i ) {
+                    $pkg = $1;
+                    last;
+                }
+            }
+            close PKGFILE;
+        }
+
+        push @found, [ $file, $pkg ];
+    }, $path ) if -d $path;
+
+    @found;
+}
+
+sub _caller {
+    my $depth = 0;
+    my $call  = caller($depth);
+    while ( $call eq __PACKAGE__ ) {
+        $depth++;
+        $call = caller($depth);
+    }
+    return $call;
+}
+
+1;

Added: jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/Base.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/Base.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,70 @@
+#line 1
+package Module::Install::Base;
+
+$VERSION = '0.64';
+
+# Suspend handler for "redefined" warnings
+BEGIN {
+	my $w = $SIG{__WARN__};
+	$SIG{__WARN__} = sub { $w };
+}
+
+### This is the ONLY module that shouldn't have strict on
+# use strict;
+
+#line 41
+
+sub new {
+    my ($class, %args) = @_;
+
+    foreach my $method ( qw(call load) ) {
+        *{"$class\::$method"} = sub {
+            shift()->_top->$method(@_);
+        } unless defined &{"$class\::$method"};
+    }
+
+    bless( \%args, $class );
+}
+
+#line 61
+
+sub AUTOLOAD {
+    my $self = shift;
+    local $@;
+    my $autoload = eval { $self->_top->autoload } or return;
+    goto &$autoload;
+}
+
+#line 76
+
+sub _top { $_[0]->{_top} }
+
+#line 89
+
+sub admin {
+    $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
+}
+
+sub is_admin {
+    $_[0]->admin->VERSION;
+}
+
+sub DESTROY {}
+
+package Module::Install::Base::FakeAdmin;
+
+my $Fake;
+sub new { $Fake ||= bless(\@_, $_[0]) }
+
+sub AUTOLOAD {}
+
+sub DESTROY {}
+
+# Restore warning handler
+BEGIN {
+	$SIG{__WARN__} = $SIG{__WARN__}->();
+}
+
+1;
+
+#line 138

Added: jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/Metadata.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/Metadata.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,315 @@
+#line 1
+package Module::Install::Metadata;
+
+use strict 'vars';
+use Module::Install::Base;
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.64';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+my @scalar_keys = qw{
+    name module_name abstract author version license
+    distribution_type perl_version tests
+};
+
+my @tuple_keys = qw{
+    build_requires requires recommends bundles
+};
+
+sub Meta            { shift        }
+sub Meta_ScalarKeys { @scalar_keys }
+sub Meta_TupleKeys  { @tuple_keys  }
+
+foreach my $key (@scalar_keys) {
+    *$key = sub {
+        my $self = shift;
+        return $self->{values}{$key} if defined wantarray and !@_;
+        $self->{values}{$key} = shift;
+        return $self;
+    };
+}
+
+foreach my $key (@tuple_keys) {
+    *$key = sub {
+        my $self = shift;
+        return $self->{values}{$key} unless @_;
+
+        my @rv;
+        while (@_) {
+            my $module = shift or last;
+            my $version = shift || 0;
+            if ( $module eq 'perl' ) {
+                $version =~ s{^(\d+)\.(\d+)\.(\d+)}
+                             {$1 + $2/1_000 + $3/1_000_000}e;
+                $self->perl_version($version);
+                next;
+            }
+            my $rv = [ $module, $version ];
+            push @rv, $rv;
+        }
+        push @{ $self->{values}{$key} }, @rv;
+        @rv;
+    };
+}
+
+sub sign {
+    my $self = shift;
+    return $self->{'values'}{'sign'} if defined wantarray and !@_;
+    $self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
+    return $self;
+}
+
+sub dynamic_config {
+	my $self = shift;
+	unless ( @_ ) {
+		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
+		return $self;
+	}
+	$self->{'values'}{'dynamic_config'} = $_[0] ? 1 : 0;
+	return $self;
+}
+
+sub all_from {
+    my ( $self, $file ) = @_;
+
+    unless ( defined($file) ) {
+        my $name = $self->name
+            or die "all_from called with no args without setting name() first";
+        $file = join('/', 'lib', split(/-/, $name)) . '.pm';
+        $file =~ s{.*/}{} unless -e $file;
+        die "all_from: cannot find $file from $name" unless -e $file;
+    }
+
+    $self->version_from($file)      unless $self->version;
+    $self->perl_version_from($file) unless $self->perl_version;
+
+    # The remaining probes read from POD sections; if the file
+    # has an accompanying .pod, use that instead
+    my $pod = $file;
+    if ( $pod =~ s/\.pm$/.pod/i and -e $pod ) {
+        $file = $pod;
+    }
+
+    $self->author_from($file)   unless $self->author;
+    $self->license_from($file)  unless $self->license;
+    $self->abstract_from($file) unless $self->abstract;
+}
+
+sub provides {
+    my $self     = shift;
+    my $provides = ( $self->{values}{provides} ||= {} );
+    %$provides = (%$provides, @_) if @_;
+    return $provides;
+}
+
+sub auto_provides {
+    my $self = shift;
+    return $self unless $self->is_admin;
+
+    unless (-e 'MANIFEST') {
+        warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
+        return $self;
+    }
+
+    # Avoid spurious warnings as we are not checking manifest here.
+
+    local $SIG{__WARN__} = sub {1};
+    require ExtUtils::Manifest;
+    local *ExtUtils::Manifest::manicheck = sub { return };
+
+    require Module::Build;
+    my $build = Module::Build->new(
+        dist_name    => $self->name,
+        dist_version => $self->version,
+        license      => $self->license,
+    );
+    $self->provides(%{ $build->find_dist_packages || {} });
+}
+
+sub feature {
+    my $self     = shift;
+    my $name     = shift;
+    my $features = ( $self->{values}{features} ||= [] );
+
+    my $mods;
+
+    if ( @_ == 1 and ref( $_[0] ) ) {
+        # The user used ->feature like ->features by passing in the second
+        # argument as a reference.  Accomodate for that.
+        $mods = $_[0];
+    } else {
+        $mods = \@_;
+    }
+
+    my $count = 0;
+    push @$features, (
+        $name => [
+            map {
+                ref($_) ? ( ref($_) eq 'HASH' ) ? %$_
+                                                : @$_
+                        : $_
+            } @$mods
+        ]
+    );
+
+    return @$features;
+}
+
+sub features {
+    my $self = shift;
+    while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
+        $self->feature( $name, @$mods );
+    }
+    return $self->{values}->{features}
+    	? @{ $self->{values}->{features} }
+    	: ();
+}
+
+sub no_index {
+    my $self = shift;
+    my $type = shift;
+    push @{ $self->{values}{no_index}{$type} }, @_ if $type;
+    return $self->{values}{no_index};
+}
+
+sub read {
+    my $self = shift;
+    $self->include_deps( 'YAML', 0 );
+
+    require YAML;
+    my $data = YAML::LoadFile('META.yml');
+
+    # Call methods explicitly in case user has already set some values.
+    while ( my ( $key, $value ) = each %$data ) {
+        next unless $self->can($key);
+        if ( ref $value eq 'HASH' ) {
+            while ( my ( $module, $version ) = each %$value ) {
+                $self->can($key)->($self, $module => $version );
+            }
+        }
+        else {
+            $self->can($key)->($self, $value);
+        }
+    }
+    return $self;
+}
+
+sub write {
+    my $self = shift;
+    return $self unless $self->is_admin;
+    $self->admin->write_meta;
+    return $self;
+}
+
+sub version_from {
+    my ( $self, $file ) = @_;
+    require ExtUtils::MM_Unix;
+    $self->version( ExtUtils::MM_Unix->parse_version($file) );
+}
+
+sub abstract_from {
+    my ( $self, $file ) = @_;
+    require ExtUtils::MM_Unix;
+    $self->abstract(
+        bless(
+            { DISTNAME => $self->name },
+            'ExtUtils::MM_Unix'
+        )->parse_abstract($file)
+     );
+}
+
+sub _slurp {
+    my ( $self, $file ) = @_;
+
+    local *FH;
+    open FH, "< $file" or die "Cannot open $file.pod: $!";
+    do { local $/; <FH> };
+}
+
+sub perl_version_from {
+    my ( $self, $file ) = @_;
+
+    if (
+        $self->_slurp($file) =~ m/
+        ^
+        use \s*
+        v?
+        ([\d_\.]+)
+        \s* ;
+    /ixms
+      )
+    {
+        my $v = $1;
+        $v =~ s{_}{}g;
+        $self->perl_version($1);
+    }
+    else {
+        warn "Cannot determine perl version info from $file\n";
+        return;
+    }
+}
+
+sub author_from {
+    my ( $self, $file ) = @_;
+    my $content = $self->_slurp($file);
+    if ($content =~ m/
+        =head \d \s+ (?:authors?)\b \s*
+        ([^\n]*)
+        |
+        =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
+        .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
+        ([^\n]*)
+    /ixms) {
+        my $author = $1 || $2;
+        $author =~ s{E<lt>}{<}g;
+        $author =~ s{E<gt>}{>}g;
+        $self->author($author); 
+    }
+    else {
+        warn "Cannot determine author info from $file\n";
+    }
+}
+
+sub license_from {
+    my ( $self, $file ) = @_;
+
+    if (
+        $self->_slurp($file) =~ m/
+        =head \d \s+
+        (?:licen[cs]e|licensing|copyright|legal)\b
+        (.*?)
+        (=head\\d.*|=cut.*|)
+        \z
+    /ixms
+      )
+    {
+        my $license_text = $1;
+        my @phrases      = (
+            'under the same (?:terms|license) as perl itself' => 'perl',
+            'GNU public license'                              => 'gpl',
+            'GNU lesser public license'                       => 'gpl',
+            'BSD license'                                     => 'bsd',
+            'Artistic license'                                => 'artistic',
+            'GPL'                                             => 'gpl',
+            'LGPL'                                            => 'lgpl',
+            'BSD'                                             => 'bsd',
+            'Artistic'                                        => 'artistic',
+        );
+        while ( my ( $pattern, $license ) = splice( @phrases, 0, 2 ) ) {
+            $pattern =~ s{\s+}{\\s+}g;
+            if ( $license_text =~ /\b$pattern\b/i ) {
+                $self->license($license);
+                return 1;
+            }
+        }
+    }
+
+    warn "Cannot determine license info from $file\n";
+    return 'unknown';
+}
+
+1;

Added: jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/WriteAll.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/inc/Module/Install/WriteAll.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,43 @@
+#line 1
+package Module::Install::WriteAll;
+
+use strict;
+use Module::Install::Base;
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.64';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+sub WriteAll {
+    my $self = shift;
+    my %args = (
+        meta        => 1,
+        sign        => 0,
+        inline      => 0,
+        check_nmake => 1,
+        @_
+    );
+
+    $self->sign(1)                if $args{sign};
+    $self->Meta->write            if $args{meta};
+    $self->admin->WriteAll(%args) if $self->is_admin;
+
+    if ( $0 =~ /Build.PL$/i ) {
+        $self->Build->write;
+    } else {
+        $self->check_nmake if $args{check_nmake};
+        unless ( $self->makemaker_args->{'PL_FILES'} ) {
+        	$self->makemaker_args( PL_FILES => {} );
+        }
+        if ($args{inline}) {
+            $self->Inline->write;
+        } else {
+            $self->Makefile->write;
+        }
+    }
+}
+
+1;

Added: jifty/branches/virtual-models/examples/Example-Todo/lib/Example/Todo/Model/Todo.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/lib/Example/Todo/Model/Todo.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,17 @@
+use strict;
+use warnings;
+
+package Example::Todo::Model::Todo;
+use Jifty::DBI::Schema;
+
+use Example::Todo::Record schema {
+
+    column done => type is 'bool';
+    column description => type is 'text';
+
+};
+
+# Your model-specific methods go here.
+
+1;
+

Added: jifty/branches/virtual-models/examples/Example-Todo/t/00-model-Todo.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/examples/Example-Todo/t/00-model-Todo.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+=head1 DESCRIPTION
+
+A basic test harness for the Todo model.
+
+=cut
+
+use Jifty::Test tests => 11;
+
+# Make sure we can load the model
+use_ok('Example::Todo::Model::Todo');
+
+# Grab a system user
+my $system_user = Example::Todo::CurrentUser->superuser;
+ok($system_user, "Found a system user");
+
+# Try testing a create
+my $o = Example::Todo::Model::Todo->new(current_user => $system_user);
+my ($id) = $o->create();
+ok($id, "Todo create returned success");
+ok($o->id, "New Todo has valid id set");
+is($o->id, $id, "Create returned the right id");
+
+# And another
+$o->create();
+ok($o->id, "Todo create returned another value");
+isnt($o->id, $id, "And it is different from the previous one");
+
+# Searches in general
+my $collection =  Example::Todo::Model::TodoCollection->new(current_user => $system_user);
+$collection->unlimit;
+is($collection->count, 2, "Finds two records");
+
+# Searches in specific
+$collection->limit(column => 'id', value => $o->id);
+is($collection->count, 1, "Finds one record with specific id");
+
+# Delete one of them
+$o->delete;
+$collection->redo_search;
+is($collection->count, 0, "Deleted row is gone");
+
+# And the other one is still there
+$collection->unlimit;
+is($collection->count, 1, "Still one left");
+

Modified: jifty/branches/virtual-models/inc/Module/Install.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install.pm	Mon May  7 16:28:32 2007
@@ -28,7 +28,7 @@
     # This is not enforced yet, but will be some time in the next few
     # releases once we can make sure it won't clash with custom
     # Module::Install extensions.
-    $VERSION = '0.64';
+    $VERSION = '0.65';
 }
 
 # Whether or not inc::Module::Install is actually loaded, the

Modified: jifty/branches/virtual-models/inc/Module/Install/AutoInstall.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/AutoInstall.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/AutoInstall.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/inc/Module/Install/Base.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Base.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Base.pm	Mon May  7 16:28:32 2007
@@ -1,7 +1,7 @@
 #line 1
 package Module::Install::Base;
 
-$VERSION = '0.64';
+$VERSION = '0.65';
 
 # Suspend handler for "redefined" warnings
 BEGIN {

Modified: jifty/branches/virtual-models/inc/Module/Install/Can.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Can.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Can.pm	Mon May  7 16:28:32 2007
@@ -11,7 +11,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/inc/Module/Install/Fetch.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Fetch.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Fetch.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/inc/Module/Install/Include.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Include.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Include.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/inc/Module/Install/Makefile.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Makefile.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Makefile.pm	Mon May  7 16:28:32 2007
@@ -7,7 +7,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -136,9 +136,13 @@
                 . "but we need version >= $perl_version";
     }
 
+    $args->{INSTALLDIRS} = $self->installdirs;
+
     my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
-    if ($self->admin->preop) {
-        $args{dist} = $self->admin->preop;
+
+    my $user_preop = delete $args{dist}->{PREOP};
+    if (my $preop = $self->admin->preop($user_preop)) {
+        $args{dist} = $preop;
     }
 
     my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
@@ -205,4 +209,4 @@
 
 __END__
 
-#line 334
+#line 338

Modified: jifty/branches/virtual-models/inc/Module/Install/Metadata.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Metadata.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Metadata.pm	Mon May  7 16:28:32 2007
@@ -6,14 +6,14 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
 
 my @scalar_keys = qw{
     name module_name abstract author version license
-    distribution_type perl_version tests
+    distribution_type perl_version tests installdirs
 };
 
 my @tuple_keys = qw{
@@ -56,6 +56,11 @@
     };
 }
 
+sub install_as_core   { $_[0]->installdirs('perl')   }
+sub install_as_cpan   { $_[0]->installdirs('site')   }
+sub install_as_site   { $_[0]->installdirs('site')   }
+sub install_as_vendor { $_[0]->installdirs('vendor') }
+
 sub sign {
     my $self = shift;
     return $self->{'values'}{'sign'} if defined wantarray and !@_;
@@ -279,9 +284,11 @@
 
     if (
         $self->_slurp($file) =~ m/
-        =head \d \s+
-        (?:licen[cs]e|licensing|copyright|legal)\b
-        (.*?)
+        (
+            =head \d \s+
+            (?:licen[cs]e|licensing|copyright|legal)\b
+            .*?
+        )
         (=head\\d.*|=cut.*|)
         \z
     /ixms
@@ -298,6 +305,7 @@
             'LGPL'                                            => 'lgpl',
             'BSD'                                             => 'bsd',
             'Artistic'                                        => 'artistic',
+            'MIT'                                             => 'MIT',
         );
         while ( my ( $pattern, $license ) = splice( @phrases, 0, 2 ) ) {
             $pattern =~ s{\s+}{\\s+}g;

Modified: jifty/branches/virtual-models/inc/Module/Install/Scripts.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Scripts.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Scripts.pm	Mon May  7 16:28:32 2007
@@ -7,7 +7,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/inc/Module/Install/Share.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Share.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Share.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -22,7 +22,7 @@
 	$self->postamble(<<"END_MAKEFILE");
 config ::
 \t\$(NOECHO) \$(MOD_INSTALL) \\
-\t\t\"$dir\" \$(INST_AUTODIR)
+\t\t"$dir" \$(INST_AUTODIR)
 
 END_MAKEFILE
 

Modified: jifty/branches/virtual-models/inc/Module/Install/Win32.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/Win32.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/Win32.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/inc/Module/Install/WriteAll.pm
==============================================================================
--- jifty/branches/virtual-models/inc/Module/Install/WriteAll.pm	(original)
+++ jifty/branches/virtual-models/inc/Module/Install/WriteAll.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.64';
+	$VERSION = '0.65';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }

Modified: jifty/branches/virtual-models/lib/Jifty.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty.pm	Mon May  7 16:28:32 2007
@@ -11,7 +11,7 @@
     require Time::Local;
 
     # Declare early to make sure Jifty::Record::schema_version works
-    $Jifty::VERSION = '0.70129';
+    $Jifty::VERSION = '0.70422';
 }
 
 =head1 NAME
@@ -149,8 +149,6 @@
         @_
     );
 
-    # Load the configuration. stash it in ->config
-    Jifty->config( Jifty::Config->new() );
 
     # Turn on logging as soon as we possibly can.
     Jifty->logger( Jifty::Logger->new( $args{'logger_component'} ) );
@@ -216,6 +214,7 @@
 sub config {
     my $class = shift;
     $CONFIG = shift if (@_);
+    $CONFIG ||= Jifty::Config->new();
     return $CONFIG;
 }
 
@@ -335,7 +334,7 @@
             }
         } 
         
-        if ($backend eq 'JiftyDBI' ) {
+        if ($backend eq 'JiftyDBI' and Jifty->handle ) {
                 @args    = (
                     db_config    => Jifty->handle->{db_config},
                     table_prefix => '_jifty_pubsub_',
@@ -355,12 +354,18 @@
 
 sub _load_plugins {
     my @plugins;
-    for my $plugin (@{Jifty->config->framework('Plugins')}) {
+    my @plugins_to_load = @{Jifty->config->framework('Plugins')};
+    for (my $i = 0; my $plugin = $plugins_to_load[$i]; $i++) {
         my $class = "Jifty::Plugin::".(keys %{$plugin})[0];
         my %options = %{ $plugin->{(keys %{$plugin})[0]} };
         Jifty::Util->require($class);
         Jifty::ClassLoader->new(base => $class)->require;
-        push @plugins, $class->new(%options);
+        my $plugin_obj = $class->new(%options);
+        push @plugins, $plugin_obj;
+        foreach my $name ($plugin_obj->prereq_plugins) {
+            next if grep { $_ eq $name } @plugins_to_load;
+            push @plugins_to_load, {$name => {}};
+        }
     }
     return @plugins;
 }
@@ -417,7 +422,8 @@
         Jifty::Util->require( $handle_class );
         Jifty->handle( $handle_class->new );
         Jifty->handle->connect();
-        Jifty->handle->check_schema_version();
+        Jifty->handle->check_schema_version()
+            unless $args{'no_version_check'};
     }
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/Action.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Action.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Action.pm	Mon May  7 16:28:32 2007
@@ -1185,7 +1185,7 @@
           value    => '%$value%',
       );
 
-      return map { $_->name } @{ $foos->item_array_ref };
+      return map { $_->name } @{ $foos->items_array_ref };
   }
 
 In this example, the "foo" field is autocompleted from names matched from the C<MyApp::Model::Foo> table. The match, in this case, matches any substring found in the database. I could have matched any item that starts with the string, ends with the string, matches other fields than the one returned, etc. It's up to you to decide.
@@ -1195,7 +1195,7 @@
 If you need a more complicated solution, you can return the autocompletion values as a list of hash references containing the keys C<value> and (optionally) C<label>:
 
   return map { { value => $_->name, label => $_->label } }
-            @{ $foos->item_array_ref };
+            @{ $foos->items_array_ref };
 
 In this case, the labels will be shown to the client, but the selected value would be returned to your application.
 

Modified: jifty/branches/virtual-models/lib/Jifty/Action/Record.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Action/Record.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Action/Record.pm	Mon May  7 16:28:32 2007
@@ -393,7 +393,7 @@
 
 L<Jifty::Action>, L<Jifty::Record>, L<Jifty::DBI::Record>,
 L<Jifty::Action::Record::Create>, L<Jifty::Action::Record::Update>,
-L<Jifty::Action::Reocrd::Delete>
+L<Jifty::Action::Record::Delete>
 
 =head1 LICENSE
 

Modified: jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm	Mon May  7 16:28:32 2007
@@ -95,12 +95,13 @@
 it creates a subclass of L<Jifty::Collection> whose C<record_class> is
 C<I<Application>::Model::I<Something>>.
 
-=item I<Application>::Action::(Create or Update or Delete)I<Anything>
+=item I<Application>::Action::(Create or Update or Delete or Search)I<Anything>
 
-If C<I<Application>::Model::I<Something>> is a valid model class, then
-it creates a subclass of L<Jifty::Action::Record::Create>,
-L<Jifty::Action::Record::Update>, or L<Jifty::Action::Record::Delete>
-whose I<record_class> is C<I<Application>::Model::I<Something>>.
+If C<I<Application>::Model::I<Something>> is a valid model class, then it
+creates a subclass of L<Jifty::Action::Record::Create>,
+L<Jifty::Action::Record::Update>, L<Jifty::Action::Record::Delete> or
+L<Jifty::Action::Record::Search> whose I<record_class> is
+C<I<Application>::Model::I<Something>>.
 
 =back
 

Modified: jifty/branches/virtual-models/lib/Jifty/Config.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Config.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Config.pm	Mon May  7 16:28:32 2007
@@ -239,6 +239,7 @@
         framework => {
             AdminMode        => 1,
             DevelMode        => 1,
+	    SkipAccessControl => 0,
             ApplicationClass => $app_class,
             TemplateClass    => $app_class."::View",
             ApplicationName  => $app_name,
@@ -347,7 +348,6 @@
 sub _expand_relative_paths {
     my $self  = shift;
     my $datum = shift;
-
     if ( ref $datum eq 'ARRAY' ) {
         return [ map { $self->_expand_relative_paths($_) } @$datum ];
     } elsif ( ref $datum eq 'HASH' ) {

Modified: jifty/branches/virtual-models/lib/Jifty/CurrentUser.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/CurrentUser.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/CurrentUser.pm	Mon May  7 16:28:32 2007
@@ -41,7 +41,7 @@
 sub new {
     my $class = shift;
     my $self  = {};
-    bless $self, $class;
+    bless $self, (ref $class || $class);
     my %args = (@_);
     if ( delete $args{'_bootstrap'} ) { $self->is_bootstrap_user(1); }
     $self->_init(%args);
@@ -65,12 +65,13 @@
 =head2 superuser
 
 A convenience constructor that returns a new CurrentUser object that's
-marked as a superuser.
+marked as a superuser. Can be called either as a class or object method.
 
 =cut
 
 sub superuser {
     my $class = shift;
+    $class = ref( $class ) if ref $class;
     my $self = $class->new();
     $self->is_superuser(1);
     return $self;

Modified: jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -1115,6 +1115,7 @@
     return $text;
 }
 
+
 =head2 template_exists PATH
 
 Returns true if PATH is a valid template inside your template root. This checks
@@ -1123,11 +1124,15 @@
 =cut
 
 sub template_exists {
-    my $self = shift;
+    my $self     = shift;
     my $template = shift;
 
-    return Jifty->handler->declare_handler->template_exists($template)
-        || Jifty->handler->mason->interp->comp_exists( $template);
+    foreach my $handler ( Jifty->handler->view_handlers) {
+        if ( Jifty->handler->view($handler)->template_exists($template) ) {
+            return 1;
+        }
+    }
+    return undef;
 }
 
 
@@ -1141,19 +1146,23 @@
 =cut
 
 sub render_template {
-    my $self = shift;
+    my $self     = shift;
     my $template = shift;
-
-    eval { 
-        my( $val) = Jifty->handler->declare_handler->template_exists($template);
-        if ($val) {
-            Jifty->handler->declare_handler->show($template);
-        } else {
-            Jifty->handler->mason->handle_comp( $template ); 
+    my $showed   = 0;
+    eval {
+        foreach my $handler ( Jifty->handler->view_handlers ) {
+            if ( Jifty->handler->view($handler)->template_exists($template) ) {
+                $showed = 1;
+                Jifty->handler->view($handler)->show($template);
+                last;
+            }
         }
-    
-    
+        if ( not $showed and my $fallback_handler = Jifty->handler->fallback_view_handler ) {
+            $fallback_handler->show($template);
+        }
+
     };
+
     my $err = $@;
 
     # Handle parse errors
@@ -1171,8 +1180,7 @@
 
         # Redirect with a continuation
         Jifty->web->_redirect( "/__jifty/error/mason_internal_error?J:C=" . $c->id );
-    }
-    elsif ($err) {
+    } elsif ($err) {
         die $err;
     }
 
@@ -1261,56 +1269,4 @@
     return @matches;
 }
 
-=head2 dump_rules
-
-Dump all defined rules in debug log. It will be called by Jifty on startup.
-
-=cut
-
-sub dump_rules {
-    my $self = shift;
-
-    no strict 'refs';
-    foreach my $stage ( qw/SETUP RUN CLEANUP/ ) {
-
-        Jifty->log->debug( "Dispatcher rules in stage $stage:");
-        foreach my $r ( @{ $self . '::RULES_' . $stage } ) {
-            Jifty->log->debug( _unroll_dumpable_rules( 0,$r ) );
-        }
-
-    }
-};
-
-=head2 _unroll_dumpable_rules LEVEL,RULE
-
-Walk all rules defined in dispatcher starting at rule
-C<RULE> and indentation level C<LEVEL>
-
-=cut
-
-sub _unroll_dumpable_rules {
-    my ($level, $rule) = @_;
-    my $log = 
-        # indentation
-        ( "    " x $level ) .
-        # op
-        ( $rule->[0] || "undef op" ) . ' ' .
-        # arguments
-        (
-            ! defined( $rule->[1] )   ? ""                                          :
-            ref $rule->[1] eq 'ARRAY' ? "'" . join("','", @{ $rule->[1] }) . "'" :
-            ref $rule->[1] eq 'HASH'  ? $rule->[1]->{method} . " '" . $rule->[1]->{""} ."'" :
-            ref $rule->[1] eq 'CODE'  ? '{...}' :
-                                        "'" . $rule->[1] . "'"
-        );
-
-    if (ref $rule->[2] eq 'ARRAY') {
-        $level++;
-        foreach my $sr ( @{ $rule->[2] } ) {
-            $log .=   _unroll_dumpable_rules( $level, $sr );
-        }
-    }
-    return $log;
-}
-
 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Handle.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Handle.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Handle.pm	Mon May  7 16:28:32 2007
@@ -49,6 +49,11 @@
     my $driver_class  = "Jifty::DBI::Handle::".  $driver;
     Jifty::Util->require($driver_class);
 
+    die "No such handle class as $driver_class. ",
+        "Check your spelling and check that your Jifty installation and ",
+        "related modules (especially Jifty::DBI) are up to date." 
+            unless $driver_class->can('isa');
+
     unshift @ISA, $driver_class;
     return $class->SUPER::new();
 }

Modified: jifty/branches/virtual-models/lib/Jifty/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Handler.pm	Mon May  7 16:28:32 2007
@@ -48,7 +48,21 @@
 
 
 
-__PACKAGE__->mk_accessors(qw(mason dispatcher declare_handler static_handler cgi apache stash));
+__PACKAGE__->mk_accessors(qw(dispatcher _view_handlers  cgi apache stash));
+
+=head2 mason
+
+
+Returns the Jifty c<HTML::Mason> handler. While this "should" be just another template handler,
+we still rely on it for little bits of Jifty infrastructure. Patches welcome.
+
+=cut
+
+sub mason {
+    my $self = shift;
+    return $self->view('Jifty::View::Mason::Handler');
+}
+
 
 =head2 new
 
@@ -66,124 +80,82 @@
     $self->dispatcher( Jifty->app_class( "Dispatcher" ) );
     Jifty::Util->require( $self->dispatcher );
     $self->dispatcher->import_plugins;
-    $self->dispatcher->dump_rules;
- 
+	eval { Jifty::Plugin::DumpDispatcher->dump_rules };
+
     $self->setup_view_handlers();
     return $self;
 }
 
-=head2 setup_view_handlers
 
-Initialize all of our view handlers. 
+=head2 view_handlers
+
+Returns a list of modules implementing view for your Jifty application.
 
 XXX TODO: this should take pluggable views
 
 =cut
 
-sub setup_view_handlers {
-    my $self = shift;
 
-    $self->declare_handler( Jifty::View::Declare::Handler->new( $self->templatedeclare_config));
-    $self->mason( Jifty::View::Mason::Handler->new( $self->mason_config ) );
-    $self->static_handler(Jifty::View::Static::Handler->new());
-}
+sub view_handlers { qw(Jifty::View::Static::Handler Jifty::View::Declare::Handler Jifty::View::Mason::Handler)}
 
 
-=head2 create_cache_directories
+=head2 fallback_view_handler
 
-Attempts to create our app's mason cache directory.
+Returns the object for our "last-resort" view handler. By default, this is the L<HTML::Mason> handler.
 
 =cut
 
-sub create_cache_directories {
-    my $self = shift;
 
-    for ( Jifty->config->framework('Web')->{'DataDir'} ) {
-        Jifty::Util->make_path( Jifty::Util->absolute_path($_) );
-    }
-}
 
+sub fallback_view_handler { my $self = shift; return $self->view('Jifty::View::Mason::Handler') }
 
-=head2 mason_config
+=head2 setup_view_handlers
+
+Initialize all of our view handlers. 
 
-Returns our Mason config.  We use the component root specified in the
-C<Web/TemplateRoot> framework configuration variable (or C<html> by
-default).  Additionally, we set up a C<jifty> component root, as
-specified by the C<Web/DefaultTemplateRoot> configuration.  All
-interpolations are HTML-escaped by default, and we use the fatal error
-mode.
 
 =cut
 
-sub mason_config {
-    my %config = (
-        static_source => 1,
-        use_object_files => 1,
-        preprocess => sub {
-            # Force UTF-8 semantics on all our components by
-            # prepending this block to all components as Mason
-            # components defaults to parse the text as Latin-1
-            ${$_[0]} =~ s!^!<\%INIT>use utf8;</\%INIT>\n!;
-        },
-        data_dir =>  Jifty::Util->absolute_path( Jifty->config->framework('Web')->{'DataDir'} ),
-        allow_globals => [
-            qw[ $JiftyWeb ],
-            @{Jifty->config->framework('Web')->{'Globals'} || []},
-        ],
-        comp_root     => [ 
-                          [application =>  Jifty::Util->absolute_path( Jifty->config->framework('Web')->{'TemplateRoot'} )],
-                         ],
-        %{ Jifty->config->framework('Web')->{'MasonConfig'} },
-    );
+sub setup_view_handlers {
+    my $self = shift;
 
-    for my $plugin (Jifty->plugins) {
-        my $comp_root = $plugin->template_root;
-        unless  ( $comp_root and -d $comp_root) {
-            next;
-        }
-        Jifty->log->debug( "Plugin @{[ref($plugin)]} mason component root added: (@{[$comp_root ||'']})");
-        push @{ $config{comp_root} }, [ ref($plugin)."-".Jifty->web->serial => $comp_root ];
+    $self->_view_handlers({});
+    foreach my $class ($self->view_handlers()) {
+        $self->_view_handlers->{$class} =  $class->new();
     }
-    push @{$config{comp_root}}, [jifty => Jifty->config->framework('Web')->{'DefaultTemplateRoot'}];
 
-    push @{ $config{comp_root} }, [jifty => Jifty->config->framework('Web')->{'DefaultTemplateRoot'}];
+}
+
+=head2 view ClassName
+
+
+Returns the Jifty view handler for C<ClassName>.
+
+=cut
+
+sub view {
+    my $self = shift;
+    my $class = shift;
+    return $self->_view_handlers->{$class};
 
-    # In developer mode, we want halos, refreshing and all that other good stuff. 
-    if (Jifty->config->framework('DevelMode') ) {
-        push @{$config{'plugins'}}, 'Jifty::Mason::Halo';
-        $config{static_source}    = 0;
-        $config{use_object_files} = 0;
-    }
-    return %config;
-        
 }
 
 
-=head2 templatedeclare_config
+=head2 create_cache_directories
+
+Attempts to create our app's mason cache directory.
 
 =cut
 
-sub templatedeclare_config {
-    
-    my %config = (
-        %{ Jifty->config->framework('Web')->{'TemplateDeclareConfig'} ||{}},
-    );
+sub create_cache_directories {
+    my $self = shift;
 
-    for my $plugin ( Jifty->plugins ) {
-        my $comp_root = $plugin->template_class;
-        Jifty::Util->require($comp_root);
-        unless (defined $comp_root and $comp_root->isa('Template::Declare') ){
-            next;
-        }
-        Jifty->log->debug( "Plugin @{[ref($plugin)]}::View added as a Template::Declare root");
-        push @{ $config{roots} }, $comp_root ;
+    for ( Jifty->config->framework('Web')->{'DataDir'} ) {
+        Jifty::Util->make_path( Jifty::Util->absolute_path($_) );
     }
-
-    push @{$config{roots}},  Jifty->config->framework('TemplateClass');
-        
-    return %config;
 }
 
+
 =head2 cgi
 
 Returns the L<CGI> object for the current request, or C<undef> if
@@ -230,30 +202,22 @@
     $self->apache( HTML::Mason::FakeApache->new( cgi => $self->cgi ) );
 
     # Build a new stash for the life of this request
-    $self->stash({});
+    $self->stash( {} );
     local $HTML::Mason::Commands::JiftyWeb = Jifty::Web->new();
 
     Jifty->web->request( Jifty::Request->new()->fill( $self->cgi ) );
     Jifty->web->response( Jifty::Response->new );
     Jifty->api->reset;
-    $_->new_request for Jifty->plugins;
-
+    for ( Jifty->plugins ) {
+        $_->new_request;
+    }
     Jifty->log->debug( "Received request for " . Jifty->web->request->path );
-    my $sent_response = 0;
-    $sent_response
-        = $self->static_handler->handle_request( Jifty->web->request->path )
-        if ( Jifty->config->framework('Web')->{'ServeStaticFiles'} );
-
-    Jifty->web->setup_session unless $sent_response;
+    Jifty->web->setup_session;
 
     # Return from the continuation if need be
     Jifty->web->request->return_from_continuation;
-
-    unless ($sent_response) {
-        Jifty->web->session->set_cookie;
-        $self->dispatcher->handle_request()
-    }
-
+    Jifty->web->session->set_cookie;
+    $self->dispatcher->handle_request();
     $self->cleanup_request();
 
 }

Modified: jifty/branches/virtual-models/lib/Jifty/I18N.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/I18N.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/I18N.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,8 @@
 use Locale::Maketext::Lexicon ();
 use Email::MIME::ContentType;
 use Encode::Guess qw(iso-8859-1);
-use File::ShareDir ':ALL';
+use File::ShareDir 'module_dir';
+use Jifty::Util;
 
 =head1 NAME
 
@@ -48,18 +49,7 @@
     my $self  = {};
     bless $self, $class;
 
-    my @import = (
-        'Gettext',Jifty->config->framework('L10N')->{'PoDir'}. '/*.po',
-        'Gettext',Jifty->config->framework('L10N')->{'DefaultPoDir'}. '/*.po'
-        );
-
-    foreach my $plugin (Jifty->plugins) {
-        local $@;
-        my $dir = eval { module_dir(ref($plugin)); };
-        next unless $dir;
-        push @import, 'Gettext';
-        push @import, $dir . '/po/*.po';
-    };
+    my @import = map {( Gettext => $_ )} _get_file_patterns();
 
     Locale::Maketext::Lexicon->import(
         {   '*' => \@import,
@@ -108,6 +98,31 @@
     return $self;
 }
 
+=head2 _get_file_patterns
+
+Get list of patterns for all PO files in the project.
+(Paths are gotten from the configuration variables and plugins).
+
+=cut
+
+sub _get_file_patterns {
+    my @ret;
+
+    push(@ret, Jifty->config->framework('L10N')->{'PoDir'});
+    push(@ret, Jifty->config->framework('L10N')->{'DefaultPoDir'});
+
+    # Convert relative paths to absolute ones
+    @ret = map { Jifty::Util->absolute_path($_) } @ret;
+
+    foreach my $plugin (Jifty->plugins) {
+        my $dir = $plugin->po_root;
+        next unless ($dir and -d $dir and -r $dir );
+        push @ret, $dir ;
+    }
+
+    return ( map { $_ . '/*.po' } @ret );
+}
+
 =head2 get_language_handle
 
 Get the lanauge language for this request.
@@ -126,18 +141,16 @@
 
 =cut
 
-my $last_modified = '';
+my $LAST_MODIFED = '';
 sub refresh {
     my $modified = join(
         ',',
-        sort map { $_ => -M $_ } map { glob("$_/*.po") } (
-            Jifty->config->framework('L10N')->{'PoDir'},
-            Jifty->config->framework('L10N')->{'DefaultPoDir'}
-        )
+        #   sort map { $_ => -M $_ } map { glob("$_/*.po") } ( Jifty->config->framework('L10N')->{'PoDir'}, Jifty->config->framework('L10N')->{'DefaultPoDir'}
+        sort map { $_ => -M $_ } map { glob($_) } _get_file_patterns()
     );
-    if ($modified ne $last_modified) {
+    if ($modified ne $LAST_MODIFED) {
         Jifty::I18N->new;
-        $last_modified = $modified;
+        $LAST_MODIFED = $modified;
     }
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/JSON.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/JSON.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/JSON.pm	Mon May  7 16:28:32 2007
@@ -73,7 +73,13 @@
 
     local $JSON::Syck::SingleQuote = $args->{singlequote};
     local $JSON::Syck::ImplicitUnicode = 1;
-    JSON::Syck::Dump($obj);
+	my $json = JSON::Syck::Dump($obj);
+	if (! $args->{singlequte}) {
+		$json =~ s/\n\n\n/\\n/gs;	# fix syck bug
+		$json =~ s/\n/\\n/gs;		# just to be safe
+		$json =~ s/\r/\\r/gs;
+	}
+	return $json;
 }
 
 # We should escape double-quotes somehow, so that we can guarantee
@@ -101,7 +107,7 @@
     local *JSON::Converter::_stringfy = sub {
         my $arg = shift;
         $arg =~ s/([\\\n'\r\t\f\b])/$esc{$1}/eg;
-        $arg =~ s/([\x00-\x07\x0b\x0e-\x1f])/'\\u00' . unpack('H2',$1)/eg;
+        $arg =~ s/([\x00-\x07\x0b\x0e-\x1f])/'\\u00' . unpack('H2',$1)/egs;
         return "'" . $arg ."'";
     };
     return JSON::objToJson($obj, $args);

Modified: jifty/branches/virtual-models/lib/Jifty/LetMe.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/LetMe.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/LetMe.pm	Mon May  7 16:28:32 2007
@@ -97,7 +97,6 @@
     return '' unless ($user->auth_token);
 
 
-
     # build an md5sum of the email token and until and our secret
     my $digest = Digest::MD5->new();
     $digest->add( $user->auth_token );
@@ -273,18 +272,22 @@
     # email must exist
 
     unless ($self->_user_from_email($self->email)) {
+        Jifty->log->debug("Token validation failed - Invalid user");
         return undef;
     }
 
     unless ($self->path) {
+        Jifty->log->debug("Token validation failed - Invalid path");
         return undef;
     }
     unless ($self->checksum_provided) {
+        Jifty->log->debug("Token validation failed - Checksum not provided");
         return undef;
     }
 
 
     unless ($self->_correct_checksum_provided) {
+        Jifty->log->debug("Token validation failed - Checksum not correct");
         return undef;
     }
 
@@ -301,11 +304,13 @@
 
 sub _correct_checksum_provided {
     my $self = shift;
+        Jifty->log->debug("LetMe checksum: ".$self->checksum_provided . " vs ". $self->generate_checksum );
     return undef
         unless ( $self->checksum_provided eq $self->generate_checksum )
         or
         ( $self->checksum_provided eq $self->generate_koremutake_checksum );
 
+    return 1;
 }
 
 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Manual/AccessControl.pod
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Manual/AccessControl.pod	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Manual/AccessControl.pod	Mon May  7 16:28:32 2007
@@ -34,23 +34,32 @@
 C<check_update_rights()> to look for the C<admin> right rather than the 
 C<update> right, if the C<FIELD> is C<paid_account>.
 
-=head1 ENABLING ACCESS CONTROL USING THE LOGIN PLUGIN
+=head1 ENABLING ACCESS CONTROL USING THE USER PLUGIN
 
-To painlessly enable the AccessControl subsystem, the
-C<Login> plugin may get enabled. This is done in the
-F<etc/config.yml> configuration file.
+To painlessly enable the AccessControl subsystem, a User plugin is available
+with an authentication plugin, the C<Authentication::Password> plugin may get 
+enabled. This is done in the F<etc/config.yml> configuration file.
 
     Plugins:
-      - Login: {}
+      - Authentication::Password: {}
 
-Then, create an C<App::Model::User> class that derives from
-C<Jifty::Plugin::Login::Model::User>, for example:
+Then, create an C<App::Model::User> class that will be override with
+C<Jifty::Plugin::User::Mixin::Model::User> and an authentication plugin 
+C<Jifty::Plugin::Authentication::Password::Mixin::Model::User>
+, for example:
 
     use strict;
     use warnings;
 
     package App::Model::User;
-    use base 'Jifty::Plugin::Login::Model::User';
+
+    use Jifty::DBI::Schema;
+
+    use App::Record schema {
+    };
+
+    use Jifty::Plugin::User::Mixin::Model::User;
+    use Jifty::Plugin::Authentication::Password::Mixin::Model::User;
 
     # Your model-specific methods go here.
 
@@ -70,7 +79,7 @@
     use App::Record schema {
         column 'extra_column_name';
 
-        column 'group' =>
+        column 'mygroup' =>
                valid_values are qw/admin moderator user/,
                default is 'user';
 
@@ -92,10 +101,10 @@
         return 0 
             if ( $type eq 'update'
                 and !$self->current_user->is_superuser
-                and $args{'column'} eq 'group' ); 
+                and $args{'column'} eq 'mygroup' ); 
 
 
-        return $self->SUPER::current_user_can($type, %args);
+        return 1;
     }
 
 Defining a method C<_init> in your C<App::CurrentUser> class gives you
@@ -115,17 +124,15 @@
         my $self = shift;
         my %args = (@_);
 
-        if (delete $args{'_bootstrap'} ) {
-            $self->is_bootstrap_user(1);
-        } elsif (keys %args) {
+        if (keys %args) {
             $self->user_object(App::Model::User->new(current_user => $self));
             $self->user_object->load_by_cols(%args);
 
-            if ( $self->user_object->group eq 'admin') {
+            if ( $self->user_object->mygroup eq 'admin') {
                 $self->is_superuser(1);
             };
 
-            $self->status($self->user_object->group);
+            $self->group($self->user_object->mygroup);
         };
         $self->SUPER::_init(%args);
     };
@@ -133,9 +140,9 @@
 With your C<App::CurrentUser>, users in group admin are superuser and you can 
 use C<< Jifty->web->current_user->group >> in your application.
 
-=head2 Templates defined by the C<Login> plugin
+=head2 Templates defined by the C<Authentication::Password> plugin
 
-To avoid the need for repetitive work, the C<Login> plugin already
+To avoid the need for repetitive work, the C<Authentication::Password> plugin already
 defines a couple of usable templates:
 
 =over 4
@@ -156,10 +163,6 @@
 a confirmation mail is sent out that has to get followed by
 the user.
 
-=item F</chgpasswd>
-
-allows a user to change his/her password.
-
 =item F</passwordreminder>
 
 after entering his/her mail address, the user will receive a mail that

Modified: jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod	Mon May  7 16:28:32 2007
@@ -125,7 +125,7 @@
 zone appropriately. All dates are stored in UTC in the database, to
 ensure consistency.
 
-=head2 How do I emulate 'created_on' field like Rails ?
+=head2 Emulate 'created_on' field like Rails ?
 
 In Rails, if you have a field named 'created_on', it's automatically
 set to the creation time of the record. How can I emulate this
@@ -154,7 +154,7 @@
         $attr->{'created_on'} = DateTime->now;
     };
 
-=head2 How do I emulate 'updated_on' ?
+=head2 Emulate 'updated_on' ?
 
 If a lot of column could change, you can override C<_set> method:
 
@@ -254,7 +254,7 @@
 pluralise or pluralises differently.
 
 
-=head2 How do I perform ajax canonicalization on a given field ?
+=head2 Perform ajax canonicalization on a given field ?
 
 Asking user to input something in a form is really common in a web
 app. For some certain form fields you want them to have a certain
@@ -371,3 +371,20 @@
   };
 
 Otherwise, everything should work as expected.
+
+=head2 Reuse Jifty models and actions outside of a Jifty app
+
+    use lib '/path/to/MyApp/lib';
+
+    use Jifty::Everything;
+    BEGIN { Jifty->new; }
+    
+    use MyApp::Model::Foo;
+    use MyApp::Action::FrobFoo;
+
+From there you can use the model and action to access your data and run your
+actions like you normally would.
+
+If you've actually installed your app into C<@INC>, you can skip the
+C<use lib> line.
+

Modified: jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm	Mon May  7 16:28:32 2007
@@ -52,7 +52,12 @@
     # On success, it expects you to return undef.
 
     local $UNIVERSAL::require::ERROR;
+
+    no warnings; # This is lexical and turns off exactly one warning below -- "Can't locate package in @ISA".
+                 # (for some reason, "no warnings 'syntax'" does not work as advertised here.)
+                 # Note that it does _not_ turn off warnings triggered in the $module itself.
     $module->require(); # We'd prefer to use Jifty::Util->require() here, but it spews crazy warnings
+
     return $UNIVERSAL::require::ERROR;
 } 
 

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin.pm	Mon May  7 16:28:32 2007
@@ -123,6 +123,18 @@
     return $dir."/web/templates";
 }
 
+=head2 po_root
+
+Returns the plugin's message catalog directory. Returns undef if it doesn't exist.
+
+=cut
+
+sub po_root {
+    my $self = shift;
+    my $dir = $self->_calculate_share();
+    return unless $dir;
+    return $dir."/po";
+}
 
 =head2 template_class
 
@@ -162,4 +174,14 @@
     return $class."::Dispatcher";
 }
 
+=head2 prereq_plugins
+
+Returns an array of plugin module names that this plugin depends on.
+
+=cut
+
+sub prereq_plugins {
+    return ();
+}
+
 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password.pm	Mon May  7 16:28:32 2007
@@ -21,4 +21,16 @@
 
 =cut
 
+
+=head2 prereq_plugins
+
+This plugin depends on the L<User|Jifty::Plugin::User> and L<LetMe|Jifty::Plugin::LetMe> plugins.
+
+=cut
+
+
+sub prereq_plugins {
+    return ('User', 'LetMe');
+}
+
 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm	Mon May  7 16:28:32 2007
@@ -52,10 +52,9 @@
         $self->result->error($msg); 
         return undef;
     }
-    else { warn $msg }
 
     # Set up our login message
-    $self->result->message( _("Welcome to %1, %2. " , Jifty->config->framework('ApplicationName') , $u->name) ." "
+    $self->result->message( _("Welcome to %1, %2." , Jifty->config->framework('ApplicationName') , $u->name) ." "
           . _(". Your email address has now been confirmed.") );
 
     # Actually do the login thing.

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm	Mon May  7 16:28:32 2007
@@ -20,22 +20,22 @@
 =cut
 
 sub arguments { 
-    return( { email => { label => 'Email',
+    return( { email => { label => _('Email'),
                            mandatory => 1,
                            ajax_validates => 1,
                             }  ,
 
               password => { type => 'password',
-                            label => 'Password',
+                            label => _('Password'),
 			    # mandatory in some cases; see validate_password
                             mandatory => 0,
                         },
               hashed_password => { type => 'hidden',
-                            label => 'Hashed Password',
+                            label => _('Hashed Password'),
                         },
               remember => { type => 'checkbox',
-                            label => 'Remember me?',
-                            hints => 'Your browser can remember your login for you',
+                            label => _('Remember me?'),
+                            hints => _('Your browser can remember your login for you'),
                             default => 0,
                           },
 	      token => { type => 'hidden',
@@ -60,7 +60,7 @@
 
     my $u = Jifty->app_class('Model', 'User')->new(current_user => Jifty->app_class('CurrentUser')->superuser);
     $u->load_by_cols( email => $email );
-    return $self->validation_error(email => 'We do not have an account that matches that email.') unless ($u->id);
+    return $self->validation_error(email => _("It doesn't look like there's an account by that name.")) unless ($u->id);
 
     return $self->validation_ok('email');
 }
@@ -83,7 +83,7 @@
 
 
     if ($token eq '') { # we have no token, validate in a standard way
-        if ($pw eq '') {
+        unless ( defined $pw && length $pw ) {
             return $self->validation_error(password => "Please fill in this field." );
         }
     } else { # we have a token, so we should have a hashed pw
@@ -149,7 +149,7 @@
         Jifty->web->session->set( login_token => '' );
     } else {                # no password hashing over the wire
         unless ( $user->id && $user->password_is($password) ) {
-            $self->result->error( _('You may have mistyped your email address or password. Give it another shot.'));
+            $self->result->error( _('You may have mistyped your email or password. Give it another shot.'));
             return;
         }
     }

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm	Mon May  7 16:28:32 2007
@@ -82,6 +82,7 @@
         return;
     }
 
+    $u->set_email_confirmed('1');
     # Log in!
     $self->result->message(_("Your password has been reset.  Welcome back."));
     Jifty->web->current_user( $CurrentUser->new( id => $u->id ) );

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -51,7 +51,7 @@
 
 =cut
 
-on qr/^(?:passwordreminder|signup)$/ => run {
+before qr'^/(?:passwordreminder|signup|lost_password)$' => run {
     redirect('/') if ( Jifty->web->current_user->id );
     set 'next' => Jifty->web->request->continuation || Jifty::Continuation->new( request => Jifty::Request->new( path => "/login" ) );
 };
@@ -60,18 +60,21 @@
 
 =cut
 
-on qr/^(?:login)$/ => run {
+before qr|^/(?:login)$| => run {
     redirect('/') if ( Jifty->web->current_user->id );
     set 'next' => Jifty->web->request->continuation || Jifty::Continuation->new( request => Jifty::Request->new( path => "/" ) );
 };
 
+before qr|(?:reset_lost_password)| => run {
+    set 'next' => Jifty->web->request->continuation || Jifty::Continuation->new( request => Jifty::Request->new( path => "/" ) );
+};
 # Send a password reminder for a lost password
 
 =head2 on passwordreminder
 
 =cut
 
-on 'passwordreminder' => run {
+before 'passwordreminder' => run {
     set 'action' => Jifty->web->new_action( class => 'SendPasswordReminder', moniker => 'password_reminder');
 };
 
@@ -82,7 +85,7 @@
 
 =cut
 
-on 'signup' => run {
+before 'signup' => run {
     set 'action' => Jifty->web->new_action( class => 'Signup');
 
 };
@@ -93,7 +96,7 @@
 
 =cut
 
-on 'login' => run {
+before 'login' => run {
     set 'action' => Jifty->web->new_action( class => 'Login');
 };
 

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm	Mon May  7 16:28:32 2007
@@ -16,16 +16,16 @@
   render_as 'unrendered',
   type is 'varchar',
   default is '',
-  label is 'Authentication token';
+  label is _('Authentication token');
     
 
 
 column password =>
   is mandatory,
   is unreadable,
-  label is 'Password',
+  label is _('Password'),
   type is 'varchar',
-  hints is 'Your password should be at least six characters',
+  hints is _('Your password should be at least six characters'),
   render_as 'password',
   filters are 'Jifty::DBI::Filter::SaltHash';
 
@@ -85,7 +85,7 @@
     my $self      = shift;
     my $new_value = shift;
 
-    return ( 0, q{Passwords need to be at least six characters long} )
+    return ( 0, _('Passwords need to be at least six characters long') )
         if length($new_value) < 6;
 
     return 1;
@@ -128,7 +128,7 @@
     my $self = shift;
     my $auth_token = '';
 
-    $auth_token .= unpack('H2', chr(int rand(255))) for (1..16);
+    $auth_token .= unpack('H2', chr(int rand(256))) for (1..16);
 
     $self->__set(column => 'auth_token', value => $auth_token);
 }

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/View.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/View.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/View.pm	Mon May  7 16:28:32 2007
@@ -27,17 +27,17 @@
 
 
 template 'signup' => page {
-    title is 'Signup';
+    title is _('Sign up');
     my ( $action, $next ) = get(qw(action next));
     Jifty->web->form->start( call => $next );
     render_param( $action => 'name' , focus => 1);
     render_param( $action => $_ ) for ( grep {$_ ne 'name'} $action->argument_names );
-    form_submit( label => _('Signup'), submit => $action );
+    form_return( label => _('Sign up'), submit => $action );
     Jifty->web->form->end();
 };
 
 template login => page {
-    { title is 'Login!' };
+    { title is _('Login!') };
     show('login_widget');
 };
 
@@ -49,16 +49,16 @@
         request => Jifty::Request->new( path => "/" ) );
     unless ( Jifty->web->current_user->id ) {
         p {
-            outs( _(        qq{No account yet? It's quick and easy.} ));
+            outs( _( "No account yet? It's quick and easy. " ));
             tangent( label => _("Sign up for an account!"), url   => '/signup');
         };
-        h3  { _(qq{Login with a password}) };
+        h3  { _('Login with a password') };
         div {
             attr { id => 'jifty-login' };
             Jifty->web->form->start( call => $next );
             render_param( $action, 'email', focus => 1 );
             render_param( $action, $_ ) for (qw(password remember));
-            form_submit( label => _(q{Login}), submit => $action );
+            form_return( label => _(q{Login}), submit => $action );
             hyperlink(
                 label => _("Lost your password?"),
                 url   => "/lost_password"
@@ -71,14 +71,14 @@
 };
 
 template 'let/reset_lost_password' => page {
-    attr { title => 'Reset lost password' };
+    my ( $next ) = get(qw(next));
+    title is 'Reset lost password' ;
     my $action = Jifty->web->new_action( class => 'ResetLostPassword' );
 
-    h2   { _('Reset lost password') };
-    form {
+    Jifty->web->form->start( call => $next );
         render_param( $action => $_ ) for ( $action->argument_names );
-        form_submit( label => _("New password") );
-    };
+        form_return( label => _("New password"), submit => $action );
+    Jifty->web->form->end();
 };
 
 template 'let/confirm_email' => sub {
@@ -87,23 +87,25 @@
 };
 
 template 'lost_password' => page {
+    my ( $next ) = get(qw(next));
     my $action = Jifty->web->new_action(
         moniker => 'password_reminder',
         class   => 'SendPasswordReminder',
     );
 
-    h2 { _('Send a link to reset your password') };
+    title is _('Send a link to reset your password');
     outs( _(  "You lost your password. A link to reset it will be sent to the following email address:"));
-
-    form {
-        render_param( $action => $_ ) for ( $action->argument_names );
-        form_submit( label => _("Send") );
-        }
+    my $focused = 0;
+    Jifty->web->form->start( call => $next );
+        render_param( $action => $_, focus => $focused++ ? 0 : 1 ) for ( $action->argument_names );
+            form_return( label => _(q{Send}), submit => $action);
+    Jifty->web->form->end;
 
 };
 
 template 'passwordreminder' => page {
-    attr { title => 'Send Password Reminder' };
+    my $next = get('next');
+     title is  _('Send a password reminder');
     my $action = Jifty->web->new_action(
         moniker => 'password_reminder',
         class   => 'SendPasswordReminder',
@@ -111,10 +113,10 @@
     h2 { _('Send a password reminder') };
     p  { _(  "You lost your password. A reminder will be send to the following mail:") };
 
-    form {
+    Jifty->web->form->start( call => $next );
         render_param( $action => $_ ) for ( $action->argument_names );
-        form_submit( label => _("Send") );
-    };
+        form_return( label => _("Send"), submit => $action);
+    Jifty->web->form->end();
 };
 
 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/ErrorTemplates/View.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/ErrorTemplates/View.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/ErrorTemplates/View.pm	Mon May  7 16:28:32 2007
@@ -104,7 +104,7 @@
                             Jifty->log->error( "Unhandled web error " . $error );
                             page {
                               title is 'Something went awry';
-                              show('_elements/error_text', error => $error );
+                              show('/__jifty/error/_elements/error_text', error => $error );
                         };
                     };
 
@@ -152,7 +152,7 @@
 
     # If we're not in devel, bail
     if ( not Jifty->config->framework("DevelMode") or not $cont ) {
-            show("_elements/error_text");
+            show("/__jifty/error/_elements/error_text");
     #    return;
     }
 

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs.pm	Mon May  7 16:28:32 2007
@@ -4,12 +4,6 @@
 package Jifty::Plugin::OnlineDocs;
 use base qw/Jifty::Plugin/;
 
-require File::Basename;
-require File::Find;
-require File::Temp;
-require File::Spec;
-require Pod::Simple::HTML;
-
 # Your plugin goes here.  If takes any configuration or arguments, you
 # probably want to override L<Jifty::Plugin/init>.
 

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,35 @@
+use warnings;
+use strict;
+
+package Jifty::Plugin::OnlineDocs::Dispatcher;
+
+=head1 NAME
+
+Jifty::Plugin::OnlineDocs::Dispatcher
+
+=head1 DESCRIPTION
+
+Load up the OnlineDocs tab when we're in Admin mode
+
+=cut
+
+
+use Jifty::Dispatcher -base;
+    
+
+on '*' => run {
+    if ( Jifty->config->framework('AdminMode') ) {
+        my $top = Jifty->web->navigation;
+        $top->child(
+            OnlineDocs =>
+              url      => "/__jifty/online_docs/",
+            label      => _('Online docs'),
+            sort_order => 999
+        );
+    }
+    return ();
+};
+
+
+1;
+

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -123,8 +123,9 @@
         }
     }
 
-    # Attempt to stringify as last resort
-    return stringify( $obj );
+    # As the last resort, return the object itself and expect the $accept-specific
+    # renderer to format the object as e.g. YAML or JSON data.
+    return $obj;
 }
 
 sub _collection_to_data {

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -28,12 +28,6 @@
             label      => _('Administration'),
             sort_order => 998
         );
-        $top->child(
-            OnlineDocs =>
-              url      => "/__jifty/online_docs/",
-            label      => _('Online docs'),
-            sort_order => 999
-        );
     }
     return ();
 };

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/View.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/View.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/View.pm	Mon May  7 16:28:32 2007
@@ -28,7 +28,7 @@
         {
             my $u      = Jifty->web->current_user->user_object;
             my $method = $u->_brief_description;
-            _( 'Hiya, %1.', $u->$method() );
+            eval {_( 'Hiya, %1.', $u->$method() )};
         }
         else {
             _("You're not currently signed in.");
@@ -64,7 +64,9 @@
 
 };
 
-
+private template 'heading_in_wrapper' => sub {
+    h1 { attr { class => 'title' }; outs_raw(get('title')) };
+};
 
 private template 'keybindings' => sub {
     div { id is "keybindings" };

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/User/Mixin/Model/User.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/User/Mixin/Model/User.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/User/Mixin/Model/User.pm	Mon May  7 16:28:32 2007
@@ -26,14 +26,14 @@
 use Jifty::Plugin::User::Record schema {
     column
         name => type is 'text',
-        label is 'Nickname',
-        hints is 'How should I display your name to other users?';
+        label is _('Nickname'),
+        hints is _('How should I display your name to other users?');
     column
         email => type is 'text',
-        label is 'Email address', default is '', is immutable, is distinct;
+        label is _('Email address'), default is '', is immutable, is distinct;
     column
-        email_confirmed => label is 'Email address confirmed?',
-        type is 'boolean', render_as 'Unrendered';
+        email_confirmed => label is _('Email address confirmed?'),
+        type is 'boolean';
 
 };
 
@@ -79,20 +79,19 @@
     my $self      = shift;
     my $new_email = shift;
     
-    return ( 0, "That $new_email doesn't look like an email address." )
+    return ( 0, _("That %1 doesn't look like an email address.", $new_email) )
         if $new_email !~ /\S\@\S/;
     
     my $temp_user = Jifty->app_class('Model','User')->new( current_user => Jifty->app_class('CurrentUser')->superuser );
     $temp_user->load_by_cols( 'email' => $new_email );
     
     # It's ok if *we* have the address we're looking for
-    return ( 0, q{It looks like somebody else is using that address. Is there a chance you have another account?} )
+    return ( 0, _('It looks like somebody else is using that address. Is there a chance you have another account?') )
         if $temp_user->id && ( !$self->id || $temp_user->id != $self->id );
     
     return 1;
 }
 
 
-
 1;
 

Modified: jifty/branches/virtual-models/lib/Jifty/Record.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Record.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Record.pm	Mon May  7 16:28:32 2007
@@ -234,6 +234,11 @@
 sub current_user_can {
     my $self  = shift;
     my $right = shift;
+    
+    if (Jifty->config->framework('SkipAccessControl')) {
+	return 1;	
+    }
+
 
     if (   $self->current_user->is_bootstrap_user
         or $self->current_user->is_superuser )
@@ -594,7 +599,7 @@
 
     # Return the application schema version
     else {
-        my $config = Jifty::Config->new;
+        my $config = Jifty->config();
         return $config->framework('Database')->{'Version'};
     }
 }

Modified: jifty/branches/virtual-models/lib/Jifty/Script/FastCGI.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Script/FastCGI.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Script/FastCGI.pm	Mon May  7 16:28:32 2007
@@ -21,7 +21,7 @@
 
  # These two lines are FastCGI-specific; skip them to run in vanilla CGI mode
  AddHandler fastcgi-script fcgi
- FastCgiServer /path/to/your/jifty/app/bin/jifty
+ FastCgiServer /path/to/your/jifty/app/bin/jifty -initial-env JIFTY_COMMAND=fastcgi 
 
  DocumentRoot /path/to/your/jifty/app/share/web/templates
  ScriptAlias / /path/to/your/jifty/app/bin/jifty/

Modified: jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm	Mon May  7 16:28:32 2007
@@ -89,7 +89,7 @@
     # Import Jifty
     Jifty::Util->require("Jifty");
     Jifty::Util->require("Jifty::Model::Metadata");
-    Jifty->new( no_handle        => 1, logger_component => 'SchemaTool',) unless (Jifty->config);
+    Jifty->new( no_handle        => 1, logger_component => 'SchemaTool',) unless Jifty->class_loader;
 }
 
 =head2 print_help

Added: jifty/branches/virtual-models/lib/Jifty/Server/Prefork.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Server/Prefork.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,29 @@
+package Jifty::Server::Prefork;
+use Net::Server::PreFork ();
+use base 'Jifty::Server';
+
+=head1 NAME
+
+Jifty::Server::Prefork - Jifty::Server that supports multiple connections
+
+=head1 SYNOPSIS
+
+In your F<etc/config.yml>:
+
+  framework:
+    Web:
+      ServerClass: Jifty::Server::Prefork
+
+=head1 METHODS
+
+=head2 net_server
+
+This module depends on the L<Net::Server::Prefork> module, which is part of
+the L<Net::Server> CPAN distribution.
+
+=cut
+
+sub net_server { 'Jifty::Server::Prefork::NetServer' }
+
+
+1;

Added: jifty/branches/virtual-models/lib/Jifty/Server/Prefork/NetServer.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Server/Prefork/NetServer.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,21 @@
+package Jifty::Server::Prefork::NetServer;
+
+use base 'Net::Server::PreFork';
+
+=head1 NAME
+
+Jifty::Server::Prefork::NetServer - Sets up children for Jifty::Server::Prefork
+
+=head1 METHODS
+
+=head2 child_init_hook
+
+Sets up the database connection when spawning a new child
+
+=cut
+
+sub child_init_hook {
+	Jifty->setup_database_connection();
+}
+
+1;

Modified: jifty/branches/virtual-models/lib/Jifty/Subs/Render.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Subs/Render.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Subs/Render.pm	Mon May  7 16:28:32 2007
@@ -54,7 +54,7 @@
 
             unless ( UNIVERSAL::can( $event_class => 'new' ) ) {
                 Jifty->log->error("Receiving unknown event $event_class from the Bus");
-                $event_class = Jifty->config->framework('ApplicationClass')."::Event";
+                $event_class = Jifty->app_class("Event");
             }
 
             Jifty->log->debug("Rendering $channel event $msg");

Modified: jifty/branches/virtual-models/lib/Jifty/Test.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Test.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Test.pm	Mon May  7 16:28:32 2007
@@ -187,16 +187,64 @@
     # Mason's disk caching sometimes causes false tests
     rmtree([ File::Spec->canonpath("$root/var/mason") ], 0, 1);
 
+$class->setup_test_database;
+
+    $class->setup_mailbox;
+}
+
+=head2 setup_test_database
+
+Create the test database. This can be overloaded if you do your databases in a
+different way.
+
+=cut
+
+sub setup_test_database {
+    my $class = shift;
+
+
+    if ($ENV{JIFTY_FAST_TEST}) {
+	local $SIG{__WARN__} = sub {};
+	eval { Jifty->new( no_version_check => 1 ); Jifty->handle->check_schema_version };
+	my $booted;
+	if (Jifty->handle && !$@) {
+	    my $baseclass = Jifty->app_class;
+	    my $schema = Jifty::Script::Schema->new;
+	    $schema->prepare_model_classes;
+	    for my $model_class ( grep {/^\Q$baseclass\E::Model::/} $schema->models ) {
+		# We don't want to get the Collections, for example.
+		next unless $model_class->isa('Jifty::DBI::Record');
+		Jifty->handle->simple_query('TRUNCATE '.$model_class->table );
+		Jifty->handle->simple_query('ALTER SEQUENCE '.$model_class->table.'_id_seq RESTART 1');
+	    }
+	    # Load initial data
+	    eval {
+		my $bootstrapper = Jifty->app_class("Bootstrap");
+		Jifty::Util->require($bootstrapper);
+		$bootstrapper->run() if $bootstrapper->can('run');
+	    };
+	    die $@ if $@;
+	    $booted = 1;
+	}
+	if (Jifty->handle) {
+	    Jifty->handle->disconnect;
+	    Jifty->handle(undef);
+	}
+	if ($booted) {
+            Jifty->new();
+	    return;
+	}
+    }
+
     Jifty->new( no_handle => 1 );
 
     my $schema = Jifty::Script::Schema->new;
-    $schema->{drop_database} =
-      $schema->{create_database} =
-        $schema->{create_all_tables} = 1;
+    $schema->{drop_database}     = 1;
+    $schema->{create_database}   = 1;
+    $schema->{create_all_tables} = 1;
     $schema->run;
 
     Jifty->new();
-    $class->setup_mailbox;
 }
 
 =head2 test_config
@@ -453,7 +501,7 @@
           if Jifty->config and Jifty->bus;
 
         # Remove testing db
-        if (Jifty->handle) {
+        if (Jifty->handle && !$ENV{JIFTY_FAST_TEST}) {
             Jifty->handle->disconnect();
             my $schema = Jifty::Script::Schema->new;
             $schema->{drop_database} = 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Test/WWW/Mechanize.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Test/WWW/Mechanize.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Test/WWW/Mechanize.pm	Mon May  7 16:28:32 2007
@@ -59,7 +59,7 @@
 
     $mech->fill_in_action_ok($mech->moniker_for('MyApp::Action::UpdateInfo'), 
                              owner_id => 'someone');
-    $mech->submit_html_ok(value => 'Save');  
+    $mech->submit_html_ok();  
 
     is($mech->action_field_value($mech->moniker_for("MyApp::Action::UpdateInfo"),
 			     'owner_id'), 
@@ -478,7 +478,7 @@
 
     return undef unless ($id);
 
-    my $object = (Jifty->config->framework('ApplicationClass')."::CurrentUser")->new(id => $id);
+    my $object = Jifty->app_class("CurrentUser")->new(id => $id);
     return $object;
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/TestServer.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/TestServer.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/TestServer.pm	Mon May  7 16:28:32 2007
@@ -77,9 +77,12 @@
 
     my @extra;
     if (my $profile_file = $ENV{JIFTY_TESTSERVER_PROFILE}) {
-        push @extra, '-d:DProf', '-MClass::Accessor::Named';
+        push @extra, '-d:DProf';
         $ENV{"PERL_DPROF_OUT_FILE_NAME"} = $profile_file;
     }
+    if ($ENV{JIFTY_TESTSERVER_NAMED_ACCESSOR}) {
+        push @extra, '-MClass::Accessor::Named';
+    }
     if (my $coverage = $ENV{JIFTY_TESTSERVER_COVERAGE}) {
         push @extra, '-MDevel::Cover'.($coverage =~ m/,/ ? "=$coverage" : '');
     }

Modified: jifty/branches/virtual-models/lib/Jifty/Upgrade.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Upgrade.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Upgrade.pm	Mon May  7 16:28:32 2007
@@ -94,7 +94,7 @@
             # Convert columns
             my ($schema) = Jifty->handle->fetch_result("SELECT sql FROM sqlite_master WHERE tbl_name = '$table_name' AND type = 'table'");
 
-            $schema =~ s/(.*create\s+table\s+)\S+(.*?\(\s*)//i;
+            $schema =~ s/(.*create\s+table\s+)\S+(.*?\(\s*)//i or die "Cannot find 'CREATE TABLE' statement in schema for '$table_name': $schema";
 
             my $new_table_name    = join( '_', $table_name, 'new', $$ );
             my $new_create_clause = "$1$new_table_name$2";

Modified: jifty/branches/virtual-models/lib/Jifty/Util.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Util.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Util.pm	Mon May  7 16:28:32 2007
@@ -201,7 +201,7 @@
 =head2 make_path PATH
 
 When handed a directory, creates that directory, starting as far up the 
-chain as necessary. (This is what 'mkdir -p' does in your shell)
+chain as necessary. (This is what 'mkdir -p' does in your shell).
 
 =cut
 

Modified: jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm	Mon May  7 16:28:32 2007
@@ -5,7 +5,6 @@
 
 use base qw/Jifty::Object Class::Accessor/;
 use Template::Declare;
-use Encode ();
 
 __PACKAGE__->mk_accessors(qw/root_class/);
 
@@ -28,11 +27,37 @@
     my $class = shift;
     my $self = {};
     bless $self,$class;
-    Template::Declare->init(@_);
+   
+    Template::Declare->init(@_ || $self->config());
     return $self;
 }
 
 
+=head2 config
+
+=cut
+
+sub config {
+    
+    my %config = (
+        %{ Jifty->config->framework('Web')->{'TemplateDeclareConfig'} ||{}},
+    );
+
+    for my $plugin ( Jifty->plugins ) {
+        my $comp_root = $plugin->template_class;
+        Jifty::Util->require($comp_root);
+        unless (defined $comp_root and $comp_root->isa('Template::Declare') ){
+            next;
+        }
+        Jifty->log->debug( "Plugin @{[ref($plugin)]}::View added as a Template::Declare root");
+        push @{ $config{roots} }, $comp_root ;
+    }
+
+    push @{$config{roots}},  Jifty->config->framework('TemplateClass');
+        
+    return %config;
+}
+
 =head2 show TEMPLATENAME
 
 Render a template. Expects that the template and any jifty methods called internally will end up being returned as a scalar, which we then print to STDOUT
@@ -41,20 +66,35 @@
 =cut
 
 sub show {
-    my $self          = shift;
+    my $self     = shift;
     my $template = shift;
 
-    no warnings qw/redefine utf8/;
+    no warnings qw/redefine/;
     local *Jifty::Web::out = sub {
         shift;    # Turn the method into a function
         goto &Template::Declare::Tags::outs_raw;
     };
-    my $content =Template::Declare::Tags::show($template);
-        unless ( Jifty->handler->apache->http_header_sent ||Jifty->web->request->is_subrequest ) {
-            Jifty->handler->apache->send_http_header();
+    my $content = Template::Declare::Tags::show( $template );
+    return unless defined $content && length $content;
+
+    my $r = Jifty->handler->apache;
+    $r->content_type || $r->content_type('text/html; charset=utf-8'); # Set up a default
+    unless ( Jifty->handler->apache->http_header_sent || Jifty->web->request->is_subrequest ) {
+        Jifty->handler->apache->send_http_header;
+    }
+
+    if ( my ($enc) = $r->content_type =~ /charset=([\w-]+)$/ ) {
+        if ( lc($enc) =~ /utf-?8/) {
+            binmode *STDOUT, ":utf8" or die "couldn't set layers: $!";
         }
+        else {
+            binmode *STDOUT, ":encoding($enc)" or die "couldn't set layers: $!";
+        }
+    } else {
+        binmode *STDOUT or die "couldn't set layers: $!";
+    }
+
     print STDOUT $content;
-    Encode::_utf8_on($content);
     return undef;
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm	Mon May  7 16:28:32 2007
@@ -6,7 +6,7 @@
 use base qw/Exporter/;
 use Template::Declare::Tags;
 
-our @EXPORT = ( qw(form hyperlink tangent redirect new_action form_submit form_next_page page wrapper request get set render_param current_user render_action render_region), @Template::Declare::Tags::EXPORT);
+our @EXPORT = ( qw(form hyperlink tangent redirect new_action form_submit form_return  form_next_page page wrapper request get set render_param current_user render_action render_region), @Template::Declare::Tags::EXPORT);
 
 
 =head1 NAME
@@ -25,22 +25,24 @@
 =head2 form CODE
 
 Takes a subroutine reference or block of perl as its only argument and renders it as a Jifty C<form>. 
-Bug: you can't currently specify arguments to form->start.
 
 
 =cut
 
-
-{
+ {
     no warnings qw/redefine/;
     sub form (&) {
         my $code = shift;
-        outs_raw( Jifty->web->form->start );
-        $code->();
-        outs_raw( Jifty->web->form->end );
-        return '';
+
+        smart_tag_wrapper {
+          outs_raw( Jifty->web->form->start(@_) );
+          $code->();
+          outs_raw( Jifty->web->form->end );
+          return '';
+        };
     }
-}
+ }
+
 
 =head2 hyperlink 
 
@@ -49,10 +51,22 @@
 =cut
 
 sub hyperlink(@) {
-    outs_raw( Jifty->web->link(@_) );
+    _function_wrapper( link => @_);
+}
+
+sub _function_wrapper {
+    my $function = shift;
+    Template::Declare->new_buffer_frame;
+    my $once= Jifty->web->$function(@_)->render || '';
+    my $content = Template::Declare->buffer->data() ||'';
+    Template::Declare->end_buffer_frame;
+    outs_raw( $content.$once); 
     return '';
+
+
 }
 
+
 =head2 tangent
 
 Shortcut for L<Jifty::Web/tangent>.
@@ -61,8 +75,7 @@
 
 
 sub tangent(@) {
-    outs_raw( Jifty->web->tangent(@_) );
-    return '';
+    _function_wrapper( tangent => @_);
 }
 
 =head2 redirect
@@ -98,9 +111,14 @@
 
 sub render_region(@) {
     unshift @_, 'name' if @_ % 2;
+    my $args = {@_};
+    my $path = $args->{path} ||= '/__jifty/empty';
+    if ($Template::Declare::Tags::self && $path !~ m|^/|) {
+	$args->{path} = $Template::Declare::Tags::self->path_for($path);
+    }
     local $Template::Declare::Tags::self = undef;
     Template::Declare->new_buffer_frame;
-    Jifty::Web::PageRegion->new(@_)->render;
+    Jifty::Web::PageRegion->new(%$args)->render;
     my $content = Template::Declare->buffer->data();
     Template::Declare->end_buffer_frame;
     Jifty->web->out($content);
@@ -143,6 +161,17 @@
     }
 }
 
+=head2 form_return
+
+Shortcut for L<Jifty::Web::Form/return>.
+
+=cut
+
+sub form_return(@) {
+    outs_raw( Jifty->web->form->return(@_) );
+    '';
+}
+
 =head2 form_submit
 
 Shortcut for L<Jifty::Web::Form/submit>.
@@ -245,10 +274,10 @@
 sub page (&) {
     my $code = shift;
     sub {
+        my $self = shift;
         Jifty->handler->apache->content_type('text/html; charset=utf-8');
-        wrapper($code);
+        wrapper(sub { $code->($self) });
     };
-
 }
 
 
@@ -267,7 +296,7 @@
     my $done_header;
     my $render_header = sub {
         no warnings qw( uninitialized redefine once );
-        $title ||= Jifty->config('framework')->{'ApplicationName'};
+        $title ||= Jifty->config->framework('ApplicationName');
 
         #   defined $title or return;
         return if $done_header++;
@@ -287,14 +316,13 @@
             show 'salutation'; 
             show 'menu'; 
         };
-            div {
+            div { attr { id is 'content'};
                 div {
                     {
                         no warnings qw( uninitialized redefine once );
 
                         local *is::title = sub {
                             shift;
-
                             for (@_) {
                                 if ( ref($_) eq 'CODE' ) {
                                     Template::Declare->new_buffer_frame;
@@ -306,15 +334,17 @@
                                 }
                             }
                             &$render_header;
-                            h1 { attr { class => 'title' }; outs_raw($title) };
+                            my $oldt = get('title'); set(title => $title);
+                            show 'heading_in_wrapper';
+                            set(title => $oldt);
                         };
-                }
 
                         &_render_pre_content_hook();
                         Jifty->web->render_messages;
                         &$content_code;
                         &$render_header unless ($done_header);
                         &_render_jifty_page_detritus();
+                }
 
                 };
             };

Modified: jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm	Mon May  7 16:28:32 2007
@@ -54,7 +54,7 @@
 sub new {
     my $package = shift;
 
-    my %p = @_;
+    my %p = @_ || $package->config;
     my $self = $package->SUPER::new( request_class => 'HTML::Mason::Request::Jifty',
                                      out_method => \&out_method,
                                      %p );
@@ -66,6 +66,57 @@
 }
 
 
+=head2 config
+
+Returns our Mason config.  We use the component root specified in the
+C<Web/TemplateRoot> framework configuration variable (or C<html> by
+default).  Additionally, we set up a C<jifty> component root, as
+specified by the C<Web/DefaultTemplateRoot> configuration.  All
+interpolations are HTML-escaped by default, and we use the fatal error
+mode.
+
+=cut
+
+sub config {
+    my %config = (
+        static_source => 1,
+        use_object_files => 1,
+        preprocess => sub {
+            # Force UTF-8 semantics on all our components by
+            # prepending this block to all components as Mason
+            # components defaults to parse the text as Latin-1
+            ${$_[0]} =~ s!^!<\%INIT>use utf8;</\%INIT>\n!;
+        },
+        data_dir =>  Jifty::Util->absolute_path( Jifty->config->framework('Web')->{'DataDir'} ),
+        allow_globals => [
+            qw[ $JiftyWeb ],
+            @{Jifty->config->framework('Web')->{'Globals'} || []},
+        ],
+        comp_root     => [ 
+                          [application =>  Jifty::Util->absolute_path( Jifty->config->framework('Web')->{'TemplateRoot'} )],
+                         ],
+        %{ Jifty->config->framework('Web')->{'MasonConfig'} },
+    );
+
+    for my $plugin (Jifty->plugins) {
+        my $comp_root = $plugin->template_root;
+        unless  ( $comp_root and -d $comp_root) {
+            next;
+        }
+        Jifty->log->debug( "Plugin @{[ref($plugin)]} mason component root added: (@{[$comp_root ||'']})");
+        push @{ $config{comp_root} }, [ ref($plugin)."-".Jifty->web->serial => $comp_root ];
+    }
+    push @{$config{comp_root}}, [jifty => Jifty->config->framework('Web')->{'DefaultTemplateRoot'}];
+
+    # In developer mode, we want halos, refreshing and all that other good stuff. 
+    if (Jifty->config->framework('DevelMode') ) {
+        push @{$config{'plugins'}}, 'Jifty::Mason::Halo';
+        $config{static_source}    = 0;
+        $config{use_object_files} = 0;
+    }
+    return %config;
+}
+
 =head2 out_method
 
 The default output method.  Sets the content-type to C<text/html;
@@ -80,17 +131,18 @@
 
     $r->content_type || $r->content_type('text/html; charset=utf-8'); # Set up a default
 
-    if ($r->content_type =~ /charset=([\w-]+)$/ ) {
-        my $enc = $1;
-	if (lc($enc) =~ /utf-?8/) {
+    if ( my ($enc) = $r->content_type =~ /charset=([\w-]+)$/ ) {
+        if ( lc($enc) =~ /utf-?8/ ) {
             binmode *STDOUT, ":utf8";
-	}
-	else {
+        }
+        else {
             binmode *STDOUT, ":encoding($enc)";
-	}
+        }
+    } else {
+        binmode *STDOUT;
     }
 
-    unless ($r->http_header_sent or not $m->auto_send_headers) {
+    unless ( $r->http_header_sent or not $m->auto_send_headers ) {
         $r->send_http_header();
     }
 
@@ -110,24 +162,24 @@
 
 sub escape_utf8 {
     my $ref = shift;
-    my $val = $$ref;
-    use bytes;
     no warnings 'uninitialized';
-    $val =~ s/&/&#38;/g;
-    $val =~ s/</&lt;/g;
-    $val =~ s/>/&gt;/g;
-    $val =~ s/\(/&#40;/g;
-    $val =~ s/\)/&#41;/g;
-    $val =~ s/"/&#34;/g;
-    $val =~ s/'/&#39;/g;
-    $$ref = $val;
-    Encode::_utf8_on($$ref);
+    $$ref =~ s/&/&#38;/g;
+    $$ref =~ s/</&lt;/g;
+    $$ref =~ s/>/&gt;/g;
+    $$ref =~ s/\(/&#40;/g;
+    $$ref =~ s/\)/&#41;/g;
+    $$ref =~ s/"/&#34;/g;
+    $$ref =~ s/'/&#39;/g;
 }
 
-
 =head2 escape_uri SCALARREF
 
-Escapes URI component according to RFC2396
+Escapes in-place URI component according to RFC2396. Takes a reference to
+perl string.
+
+*Note* that octets would be treated as latin1 encoded sequence and converted
+to UTF-8 encoding and then escaped. So this sub always provide UTF-8 escaped
+string. See also L<Encode> for more info about converting.
 
 =cut
 
@@ -135,18 +187,38 @@
     my $ref = shift;
     $$ref = Encode::encode_utf8($$ref);
     $$ref =~ s/([^a-zA-Z0-9_.!~*'()-])/uc sprintf("%%%02X", ord($1))/eg;
-    Encode::_utf8_on($$ref);
 }
 
 
-=head2 handle_comp COMPONENT
+=head2 template_exists COMPONENT
+
+A convenience method for $self->interp->comp_exists().  
+(Jifty uses this method as part of its standard Templating system API).
+
+=cut
+
+sub template_exists {
+	my $self = shift;
+	return $self->interp->comp_exists(@_);
+}
+
+
+=head2 show COMPONENT
 
 Takes a component path to render.  Deals with setting up a global
 L<HTML::Mason::FakeApache> and Request object, and calling the
 component.
 
+=head2 handle_comp
+
+A synonym for show
+
 =cut
 
+sub show {
+    shift->handle_comp(@_);
+}
+
 sub handle_comp {
     my ($self, $comp) = (shift, shift);
 

Modified: jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm	Mon May  7 16:28:32 2007
@@ -55,13 +55,25 @@
 }
 
 
-=head2 handle_request $path
+=head2 show $path
 
 Handle a request for C<$path>. If we can't find a static file of that name, return undef.
 
 
 =cut
 
+=head2 handle_request $path
+
+
+An alias for L</show>
+
+=cut
+
+
+sub show {
+    shift->handle_request(@_);
+}
+
 sub handle_request {
     my $self = shift;
     my $path = shift;
@@ -113,6 +125,16 @@
 
 =cut
 
+=head2 template_exists $path
+
+An alias for L</file_path>.
+
+=cut
+
+sub template_exists {
+    shift->file_path(@_);
+}
+
 sub file_path {
     my $self    = shift;
     my $file    = shift;

Modified: jifty/branches/virtual-models/lib/Jifty/Web.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web.pm	Mon May  7 16:28:32 2007
@@ -62,8 +62,10 @@
     yui/dom.js
     yui/event.js
     yui/calendar.js
+    yui/element-beta.js
     yui/tabview.js
     yui/container.js
+    yui/menu.js
     app.js
     app_behaviour.js
     css_browser_selector.js
@@ -776,7 +778,8 @@
 
 sub return {
     my $self = shift;
-    my %args = (@_);
+    my %args = (to => undef,
+                @_);
     my $continuation = Jifty->web->request->continuation;
     if (not $continuation and $args{to}) {
         $continuation = Jifty::Continuation->new(

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Form.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Form.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Form.pm	Mon May  7 16:28:32 2007
@@ -226,6 +226,26 @@
     return '';
 }
 
+=head2 return MESSAGE, [PARAMETERS]
+
+Renders a return button with the text MESSAGE on it (which will be
+HTML escaped).  Returns the empty string (for ease of use in
+interpolation).  Any extra PARAMETERS are passed to
+L<Jifty::Web::Form::Field::Button>'s constructor.
+
+=cut
+
+sub return {
+    my $self = shift;
+
+    my $button = Jifty->web->return(as_button => 1, @_);
+    Jifty->web->out(qq{<div class="submit_button">});
+    $button->render_widget;
+    Jifty->web->out(qq{</div>});
+
+    return '';
+}
+
 =head2 end
 
 Renders the closing form tag (including rendering errors for and

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Form/Element.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Form/Element.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Form/Element.pm	Mon May  7 16:28:32 2007
@@ -111,6 +111,10 @@
 A hashref of arguments to pass to the effect when it is created.  These
 can be used to change the duration of the effect, for instance.
 
+=item beforeclick => STRING
+
+String contains some Javascript code to be used before a click.
+
 =item confirm => STRING
 
 Prompt the user with a Javascript confirm dialog with the given text
@@ -234,6 +238,7 @@
         my @fragments;
         my %actions;    # Maps actions => disable?
         my $confirm;
+        my $beforeclick;
 
         for my $hook (grep {ref $_ eq "HASH"} (@{$value})) {
 
@@ -254,6 +259,11 @@
                 $confirm = $hook->{confirm};
             }
 
+            # Some code usable before onclick
+            if ($hook->{beforeclick}) {
+                $beforeclick = $hook->{beforeclick};
+            }
+
             # Placement
             if (exists $hook->{append}) {
                 @args{qw/mode path/} = ('Bottom', $hook->{append});
@@ -309,11 +319,14 @@
         my $string = join ";", (grep {not ref $_} (ref $value eq "ARRAY" ? @{$value} : ($value)));
         if (@fragments or %actions) {
 
-            my $update = "update( ". Jifty::JSON::objToJson( {actions => \%actions, fragments => \@fragments }, {singlequote => 1}) .", this );";
+            my $update = Jifty->web->escape("update( ". Jifty::JSON::objToJson( {actions => \%actions, fragments => \@fragments }, {singlequote => 1}) .", this );");
             $string .= $self->javascript_preempt ? "return $update" : "$update; return true;";
         }
         if ($confirm) {
-            $string = "if(!confirm(" . Jifty::JSON::objToJson($confirm, {singlequote => 1}) . ")) return false;" . $string;
+            $string = Jifty->web->escape("if(!confirm(" . Jifty::JSON::objToJson($confirm, {singlequote => 1}) . ")) { Event.stop(event); return false }") . $string;
+        }
+        if ($beforeclick) {
+           $string = Jifty->web->escape($beforeclick) . $string;
         }
         $response .= qq| $trigger="$string"|;
     }
@@ -389,7 +402,7 @@
     Jifty->web->out(
         '<script type="text/javascript"><!--' .
         "\n" .
-        $self->key_binding_javascript .
+        Jifty->web->escape($self->key_binding_javascript).
         "\n" .
         "--></script>");
     return '';

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Form/Field.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Form/Field.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Form/Field.pm	Mon May  7 16:28:32 2007
@@ -546,7 +546,7 @@
     my $field = '<span';
     $field .= qq! class="@{[ $self->classes ]}"> !;
     # XXX: force stringify the value because maketext is buggy with overloaded objects.
-    $field .= Jifty->web->escape(_("@{[$self->current_value]}")) if defined $self->current_value;
+    $field .= Jifty->web->escape("@{[$self->current_value]}") if defined $self->current_value;
     $field .= qq!</span>\n!;
     Jifty->web->out($field);
     return '';

Added: jifty/branches/virtual-models/lib/Jifty/Web/Form/Field/Collection.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Form/Field/Collection.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,68 @@
+use warnings;
+use strict;
+ 
+package Jifty::Web::Form::Field::Collection;
+
+use base qw/Jifty::Web::Form::Field/;
+
+=head2 render_widget
+
+Renders the whole collection of available values.
+
+=cut
+
+sub render_widget {
+    my $self  = shift;
+
+    for my $opt (@{ $self->action->available_values($self->name) }) {
+        $self->render_option($opt);
+    }
+}
+
+=head2 render_label
+
+Render a label for our own.  We need to output the label as a span
+instead since the labels are associated with the individual options.
+
+=cut
+
+sub render_label {
+    my $self = shift;
+    Jifty->web->out(
+        qq!<span class="label @{[$self->classes]}">@{[_($self->label) ]}</span>\n!
+    );
+
+    return '';
+}
+
+=head2 render_option option
+
+Renders a normal input field.
+
+=cut
+
+sub render_option {
+    my $self = shift;
+    my $opt = shift;
+    my $display = $opt->{'display'};
+    my $value   = defined $opt->{'value'} ? $opt->{'value'} : "0";
+
+    my $id = $self->element_id . "-" . $value;
+    $id =~ s/\s+/_/;
+    my $field = qq! <input type="text" !;
+    $field .= qq! name="@{[ $self->input_name ]}"!;
+    $field .= qq! id="@{[ $id ]}"!;
+    $field .= qq! value="0"!;
+    $field .= $self->_widget_class;
+
+    $field .= qq{ /><label for="@{[ $id ]}"};
+    $field .= $self->_widget_class;
+    $field .= qq{ >$display</label>\n };
+
+    $field = qq{<span class="multitext">$field</span>};
+
+    Jifty->web->out($field);
+    '';
+}
+
+1;

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm	Mon May  7 16:28:32 2007
@@ -193,7 +193,6 @@
     '';
 }
 
-
 =head2 render_as_context_menu
 
 Render this menu with html markup as an inline dropdown menu.
@@ -226,7 +225,7 @@
     my @kids = $self->children;
     my $id   = Jifty->web->serial;
     Jifty->web->out( qq{<li class="toplevel }
-            . ( $self->active ? 'open active' : 'closed' ) . qq{">}
+            . ( $self->active ? 'active' : 'closed' ) . qq{">}
             . qq{<span class="title">} );
     Jifty->web->out( $self->as_link );
     Jifty->web->out(qq{</span>});
@@ -254,6 +253,46 @@
 
 }
 
+=head2 render_as_yui_menubar
+
+Render menubar with YUI menu, suitable for an application's menu.
+It can support arbitary levels of submenu.
+
+=cut
+
+sub render_as_yui_menubar {
+    my $self = shift;
+    my $id   = Jifty->web->serial;
+    $self->_render_as_yui_menu_item("yuimenubar", $id);
+    Jifty->web->out(qq|<script type="text/javascript">\n|
+        . qq|YAHOO.util.Event.onContentReady("|.$id.qq|", function() {\n|
+        . qq|var menu = new YAHOO.widget.MenuBar("|.$id.qq|", { autosubmenudisplay:true, hidedelay:750, lazyload:true });\n|
+        . qq|menu.render();\n|
+        . qq|});</script>|
+        );
+    '';
+}
+
+sub _render_as_yui_menu_item {
+    my ($self, $class, $id) = @_;
+    my @kids = $self->children 
+        or return;
+    
+    Jifty->web->out(
+        qq{<div}
+        . ($id ? qq{ id="$id"} : "")
+        . qq{ class="$class"><div class="bd"><ul>}
+    );
+    for (@kids) {
+        Jifty->web->out( qq{<li class="${class}item }
+        . ($_->active? 'active' : '') . qq{">});
+        Jifty->web->out( $_->as_link );
+        $_->_render_as_yui_menu_item("yuimenu");
+        Jifty->web->out( qq{</li>});
+    }
+    Jifty->web->out(qq{</ul></div></div>});
+}
+
 =head2 as_link
 
 Return this menu item as a C<Jifty::Web::Link>, either the one we were

Modified: jifty/branches/virtual-models/lib/Jifty/Web/PageRegion.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/PageRegion.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/PageRegion.pm	Mon May  7 16:28:32 2007
@@ -320,21 +320,27 @@
     # While we're inside this region, have Mason to tack its response
     # onto a variable and not send headers when it does so
     #XXX TODO: There's gotta be a better way to localize it
-    my $region_content = '';
 
     # template-declare based regions are printing to stdout
     my $td_out = '';
-    Encode::_utf8_on($td_out);
-    open my $output_fh, '>>:utf8', \$td_out;
-    local *STDOUT = $output_fh;
-
-    local $main::DEBUG=1;
-    # Call into the dispatcher
-    Jifty->handler->dispatcher->handle_request;
+    {
+        open my $output_fh, '>>', \$td_out;
+        local *STDOUT = $output_fh;
+
+        local $main::DEBUG = 1;
+        # Call into the dispatcher
+        Jifty->handler->dispatcher->handle_request;
+    }
 
     Jifty->handler->mason->interp->out_method($orig_out);
 
-    $$out_method .= $td_out if length($td_out);
+    return unless length $td_out;
+
+    if ( my ($enc) = Jifty->handler->apache->content_type =~ /charset=([\w-]+)$/ ) {
+        $td_out = Encode::decode($enc, $td_out);
+    }
+    $$out_method .= $td_out;
+
     return;
 }
 

Added: jifty/branches/virtual-models/lib/Jifty/Web/Session/None.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Session/None.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,162 @@
+package Jifty::Web::Session::None;
+
+use warnings;
+use strict;
+
+=head1 NAME
+
+Jifty::Web::Session::None - A null session handler for jifty
+
+=head1 DESCRIPTION
+
+Jifty depends on its sessions to keep users logged in, to store
+continuations and to allow developers to store user-specific data.
+In general, you don't want to disable them. But sometimes, the
+development benefits of Jifty lead you to build applications that
+genuinely don't want per-user sessions. That's where 
+C<Jifty::Web::Session::None> comes in. By specifying that you want
+to use C<Jifty::Web::Session::None> as your Jifty session handler, 
+you tell Jifty to avoid ever reading, writing or storing a user session.
+No cookies get set. Nothing gets stored in the database.
+
+=head1 USAGE
+
+In your C<etc/config.yml>:
+
+ ---
+ framework:
+   Web:
+     SessionClass:: Jifty::Web::Session::None
+ 
+=cut
+
+=head1 METHODS
+
+All methods in this class are dummy methods which do no work. This class
+mocks the API provided by C<Jifty::Web::Session>.
+
+=cut
+
+=head2 new
+
+Takes no arguments. Returns a L<Jifty::Web::Session::None>.
+
+=cut
+
+sub new {
+    my $class = shift;
+    return bless {}, $class;
+}
+
+=head2 id
+
+Returns false.
+
+=cut
+
+sub id {return undef }
+
+=head2 load
+
+Returns true.
+
+=cut
+
+sub load { return 1}
+
+=head2 unload
+
+Returns true.
+
+=cut
+
+sub unload { return 1}
+
+=head2 loaded
+
+Returns true.
+
+=cut
+
+sub loaded { return 1};
+
+=head2 get
+
+Returns false.
+
+=cut
+
+sub get { return undef;}
+
+=head2 set
+
+Returns false.
+
+=cut
+
+sub set { return undef;}
+
+=head2 remove
+
+Returns true.
+
+=cut
+
+sub remove { return 1}
+
+=head2 set_continuation
+
+Returns false.
+
+=cut
+sub set_continuation { return undef}
+
+=head2 get_continuation
+
+Returns false.
+
+=cut
+
+sub get_continuation {return undef}
+
+=head2 remove_continuation
+
+Returns false.
+
+=cut
+
+sub remove_continuation {return undef}
+
+=head2 continuations
+
+Returns false.
+
+=cut
+
+sub continuations { return undef}
+
+=head2 set_cookie
+
+Returns false.
+
+=cut
+
+sub set_cookie { return undef}
+
+=head2 cookie_name
+
+Returns false.
+
+=cut
+
+sub cookie_name { return undef}
+
+=head2 expires
+
+Returns false.
+
+=cut
+
+sub expires {return undef}
+
+1;

Added: jifty/branches/virtual-models/plugins/DumpDispatcher/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/DumpDispatcher/Makefile.PL	Mon May  7 16:28:32 2007
@@ -0,0 +1,8 @@
+use inc::Module::Install;
+name('Jifty-Plugin-DumpDispatcher');
+version('0.01');
+requires('Jifty' => '0.70117');
+
+install_share;
+
+WriteAll;

Added: jifty/branches/virtual-models/plugins/DumpDispatcher/lib/Jifty/Plugin/DumpDispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/DumpDispatcher/lib/Jifty/Plugin/DumpDispatcher.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,74 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::DumpDispatcher;
+use base qw/Jifty::Plugin/;
+
+=head1 NAME
+
+Jifty::Plugin::DumpDispatcher
+
+=head1 DESCRIPTION
+
+When activated in C<config.yml> with:
+
+  Plugins:
+    - DumpDispatcher: {}
+
+it will dump all dispatcher rules in debug log.
+
+=head2 dump_rules
+
+Dump all defined rules in debug log. It is called by Jifty, after
+C<< Jifty->dispatcher->import_plugins >> on startup.
+
+=cut
+
+sub dump_rules {
+    my $self = shift;
+	#my %args = @_;
+
+    no strict 'refs';
+    foreach my $stage ( qw/SETUP RUN CLEANUP/ ) {
+
+		my $rules = Jifty->app_class( 'Dispatcher' ) . '::RULES_' . $stage;
+
+        Jifty->log->debug( "Dispatcher rules in stage $stage:");
+		Jifty->log->debug( _unroll_dumpable_rules( 0, $_ ) ) foreach @{ $rules }
+
+    }
+};
+
+=head2 _unroll_dumpable_rules LEVEL,RULE
+
+Walk all rules defined in dispatcher starting at rule
+C<RULE> and indentation level C<LEVEL>
+
+=cut
+
+sub _unroll_dumpable_rules {
+    my ($level, $rule) = @_;
+    my $log = 
+        # indentation
+        ( "    " x $level ) .
+        # op
+        ( $rule->[0] || "undef op" ) . ' ' .
+        # arguments
+        (
+            ! defined( $rule->[1] )   ? ""                                          :
+            ref $rule->[1] eq 'ARRAY' ? "'" . join("','", @{ $rule->[1] }) . "'" :
+            ref $rule->[1] eq 'HASH'  ? $rule->[1]->{method} . " '" . $rule->[1]->{""} ."'" :
+            ref $rule->[1] eq 'CODE'  ? '{...}' :
+                                        "'" . $rule->[1] . "'"
+        );
+
+    if (ref $rule->[2] eq 'ARRAY') {
+        $level++;
+        foreach my $sr ( @{ $rule->[2] } ) {
+            $log .=   _unroll_dumpable_rules( $level, $sr );
+        }
+    }
+    return $log;
+}
+
+1;

Modified: jifty/branches/virtual-models/plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action/FileEditor.pm
==============================================================================
--- jifty/branches/virtual-models/plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action/FileEditor.pm	(original)
+++ jifty/branches/virtual-models/plugins/EditInPlace/lib/Jifty/Plugin/EditInPlace/Action/FileEditor.pm	Mon May  7 16:28:32 2007
@@ -104,7 +104,7 @@
     my $path = $self->argument_value('source_path');
     my $type = $self->argument_value('file_type');
     my $out = '';
-    my %cfg = Jifty->handler->mason_config;
+    my %cfg = Jifty->handler->mason->config;
     
     my($local_template_base, $qualified_path);
     if ($type eq "mason_component") {

Added: jifty/branches/virtual-models/plugins/ExtJS/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/Makefile.PL	Mon May  7 16:28:32 2007
@@ -0,0 +1,9 @@
+use inc::Module::Install;
+name('Jifty-Plugin-ExtJS');
+version('0.01');
+license('Perl');
+requires('Jifty' => '0.60722');
+
+install_share;
+
+WriteAll;

Added: jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,59 @@
+use strict;
+use warnings;
+
+=head1 NAME
+
+Jifty::Plugin::ExtJS
+
+=cut
+
+package Jifty::Plugin::ExtJS;
+use base qw/Jifty::Plugin/;
+
+=head1 SYNOPSIS
+
+In etc/config.yml
+
+    Plugins:
+      - ExtJS: {}
+
+If you want to include javascript files by hand:
+
+    Plugins:
+      - ExtJS:
+        IncludeDefault: 0
+
+You have to include Ext's CSS file by hand. Just add this line in main.css:
+
+    @import "extjs/ext-all.css";
+
+
+=head1 DESCRIPTION
+
+ExtJS plugin contains necessary files to run Ext JavaScript library.
+Ext supports YUI, prototype and jQuery. This plugin uses YUI by default.
+
+    Ext: http://extjs.com/
+
+
+=cut
+
+# Your plugin goes here.  If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+sub init {
+    my $self = shift;
+    my %args = (IncludeDefault => 1, @_);
+
+    return unless $args{IncludeDefault};
+
+    Jifty->web->javascript_libs([
+        "extjs/adapter/yui/yui-utilities.js",
+        "extjs/adapter/yui/ext-yui-adapter.js",
+        "extjs/ext-all.js",
+        "extjs/ext-config.js",
+        @{ Jifty->web->javascript_libs }
+    ]);
+}
+
+1;

Added: jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/lib/Jifty/Plugin/ExtJS/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::ExtJS::Dispatcher;
+use Jifty::Dispatcher -base;
+
+# Put any plugin-specific dispatcher rules here.
+
+1;

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/README.txt
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/README.txt	Mon May  7 16:28:32 2007
@@ -0,0 +1,3 @@
+2006-11-21 jvs:
+ext-all.css contains all of the other css files combined and stripped of comments (except themes).
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/basic-dialog.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/basic-dialog.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,263 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-dlg-proxy {
+	background-image: url(/static/images/extjs/default/gradient-bg.gif);
+	background-color:#c3daf9;
+	border:1px solid #6593cf;
+	z-index:10001;
+	overflow:hidden;
+	position:absolute;
+	left:0;top:0;
+}
+.x-dlg-shadow{
+	background:#aaaaaa;
+	position:absolute;
+	left:0;top:0;
+}
+.x-dlg-focus{
+	-moz-outline:0 none;
+	outline:0 none;
+	width:0;
+	height:0;
+	overflow:hidden;
+	position:absolute;
+	top:0;
+	left:0;
+}
+.x-dlg-mask{
+	z-index:10000;   
+   display:none;
+   position:absolute;
+   top:0;
+   left:0;
+   -moz-opacity: 0.5;
+   opacity:.50;
+   filter: alpha(opacity=50);
+   background-color:#CCC;
+}
+body.x-body-masked select {
+	visibility:hidden;
+}
+body.x-body-masked .x-dlg select {
+	visibility:visible;
+}
+.x-dlg{
+	z-index:10001;
+	overflow:hidden;
+	position:absolute;
+	left:300;top:0;
+}
+.x-dlg .x-dlg-hd {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) repeat-x 0 -82px;
+	background-color:navy;
+	color:#FFF;
+	font:bold 12px "sans serif", tahoma, verdana, helvetica;
+	overflow:hidden;
+	padding:5px;
+    white-space: nowrap;
+}
+.x-dlg .x-dlg-hd-left {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) no-repeat 0 -41px;
+	padding-left:3px;
+	margin:0;
+}
+.x-dlg .x-dlg-hd-right {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) no-repeat right 0;
+	padding-right:3px;
+}
+.x-dlg .x-dlg-dlg-body{
+	background:url(/static/images/extjs/default/layout/gradient-bg.gif);
+	border:1px solid #6593cf;
+	border-top:0 none;
+	padding:10px;
+	position:absolute;
+	top:24px;left:0;
+	z-index:1;
+	overflow:hidden;
+}
+.x-dlg-collapsed .x-resizable-handle{
+    display:none;
+}
+.x-dlg .x-dlg-bd{
+	overflow:hidden;
+}
+.x-dlg .x-dlg-ft{
+	overflow:hidden;
+	padding:5px;
+	padding-bottom:0;
+}
+.x-dlg .x-tabs-body{
+	background:white;
+	overflow:auto;
+}
+.x-dlg .x-tabs-top .x-tabs-body{
+	border:1px solid #6593cf;
+	border-top:0 none;
+}
+.x-dlg .x-tabs-bottom .x-tabs-body{
+	border:1px solid #6593cf;
+	border-bottom:0 none;
+}
+.x-dlg .x-layout-container  .x-tabs-body{
+	border:0 none;
+}
+.x-dlg .inner-tab{
+	margin:5px;
+}
+.x-dlg .x-dlg-ft .x-btn{
+	margin-right:5px;
+	float:right;
+	clear:none;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns td {
+	border:0;
+	padding:0;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-right table{
+	float:right;
+	clear:none;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-left table{
+	float:left;
+	clear:none;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-center{
+	text-align:center; /*ie*/
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-center table{
+	margin:0 auto; /*everyone else*/
+}
+.x-dlg-draggable .x-dlg-hd{
+	cursor:move;
+}
+.x-dlg-closable .x-dlg-hd{
+	padding-right:22px;
+}
+.x-dlg-toolbox {
+    position:absolute;
+	top:4px;
+	right:4px;
+	z-index:6;
+    width:40px;
+    cursor:default;
+    height:15px;
+    background:transparent;
+}
+.x-dlg .x-dlg-close, .x-dlg .x-dlg-collapse {
+    float:right;
+    height:15px;
+	width:15px;
+	margin:0;
+    margin-left:2px;
+    padding:0;
+	line-height:1px;
+	font-size:1px;
+	background-repeat:no-repeat;
+	cursor:pointer;
+	visibility:inherit;
+}
+.x-dlg .x-dlg-close {
+    background-image:url(/static/images/extjs/default/basic-dialog/close.gif);
+}
+.x-dlg .x-dlg-collapse {
+    background-image:url(/static/images/extjs/default/basic-dialog/collapse.gif);
+}
+.x-dlg-collapsed .x-dlg-collapse {
+    background-image:url(/static/images/extjs/default/basic-dialog/expand.gif);
+}
+.x-dlg .x-dlg-close-over, .x-dlg .x-dlg-collapse-over {
+    
+}
+.x-dlg div.x-resizable-handle-east{
+	background-image:url(/static/images/extjs/default/basic-dialog/e-handle.gif);
+	border:0;
+	background-position:right;
+	margin-right:0;
+}
+.x-dlg div.x-resizable-handle-south{
+	background-image:url(/static/images/extjs/default/sizer/s-handle-dark.gif);
+	border:0;
+	height:6px;
+}
+.x-dlg div.x-resizable-handle-west{
+	background-image:url(/static/images/extjs/default/basic-dialog/e-handle.gif);
+	border:0;
+	background-position:1px;
+}
+.x-dlg div.x-resizable-handle-north{
+	background-image:url(/static/images/extjs/default/s.gif);
+	border:0;
+}
+.x-dlg div.x-resizable-handle-northeast, .ytheme-gray .x-dlg div.x-resizable-handle-northeast{
+	background-image:url(/static/images/extjs/default/s.gif);
+	border:0;
+}
+.x-dlg div.x-resizable-handle-northwest, .ytheme-gray .x-dlg div.x-resizable-handle-northwest{
+	background-image:url(/static/images/extjs/default/s.gif);
+	border:0;
+}
+.x-dlg div.x-resizable-handle-southeast{
+	background-image:url(/static/images/extjs/default/basic-dialog/se-handle.gif);
+	background-position: bottom right;
+	width:8px;
+	height:8px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-southwest{
+	background-image:url(/static/images/extjs/default/sizer/sw-handle-dark.gif);
+	background-position: top right;
+	margin-left:1px;
+	margin-bottom:1px;
+	border:0;
+}
+
+#x-msg-box .x-dlg-ft .x-btn{
+	float:none;
+	clear:none;
+	margin:0 3px;
+}
+
+#x-msg-box .x-dlg-bd {
+	padding:5px;
+	overflow:hidden !important;
+	font:normal 13px verdana,tahoma,sans-serif;
+}
+#x-msg-box .ext-mb-input {
+	margin-top:4px;
+	width:95%;
+}
+#x-msg-box .ext-mb-textarea {
+	margin-top:4px;
+	font:normal 13px verdana,tahoma,sans-serif;
+}
+#x-msg-box .ext-mb-progress-wrap {
+	margin-top:4px;
+	border:1px solid #6593cf;
+}
+#x-msg-box .ext-mb-progress {
+	height:18px;
+	background: #e0e8f3 url(/static/images/extjs/default/qtip/bg.gif) repeat-x;
+}
+#x-msg-box .ext-mb-progress-bar {
+	height:18px;
+	overflow:hidden;
+	width:0;
+	background:#8BB8F3;
+	border-top:1px solid #B2D0F7;
+	border-bottom:1px solid #65A1EF;
+	border-right:1px solid #65A1EF;
+}
+
+#x-msg-box .x-msg-box-wait {
+	background: transparent url(/static/images/extjs/default/grid/loading.gif) no-repeat left;
+    display:block;
+    width:300px;
+    padding-left:18px;
+    line-height:18px;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/box.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/box.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,111 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+/*
+ Creates rounded, raised boxes like on the Ext website - the markup isn't pretty:
+  <div class="x-box-blue">
+        <div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>
+        <div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc">
+            <h3>YOUR TITLE HERE (optional)</h3>
+            <div>YOUR CONTENT HERE</div>
+        </div></div></div>
+        <div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>
+    </div>
+ */
+
+.x-box-tl {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat 0 0;
+    zoom:1;
+}
+
+.x-box-tc {
+	height: 8px;
+	background: transparent url(/static/images/extjs/default/box/tb.gif) repeat-x 0 0;
+	overflow: hidden;
+}
+
+.x-box-tr {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat right -8px;
+}
+
+.x-box-ml {
+	background: transparent url(/static/images/extjs/default/box/l.gif) repeat-y 0;
+	padding-left: 4px;
+	overflow: hidden;
+    zoom:1;
+}
+
+.x-box-mc {
+	background: #eee url(/static/images/extjs/default/box/tb.gif) repeat-x 0 -16px;
+	padding: 4px 10px;
+	font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif;
+	color: #393939;
+	font-size: 12px;
+}
+
+.x-box-mc h3 {
+	font-size: 14px;
+	font-weight: bold;
+	margin: 0 0 4 0;
+    zoom:1;
+}
+
+.x-box-mr {
+	background: transparent url(/static/images/extjs/default/box/r.gif) repeat-y right;
+	padding-right: 4px;
+	overflow: hidden;
+}
+
+.x-box-bl {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat 0 -16px;
+    zoom:1;
+}
+
+.x-box-bc {
+	background: transparent url(/static/images/extjs/default/box/tb.gif) repeat-x 0 -8px;
+	height: 8px;
+	overflow: hidden;
+}
+
+.x-box-br {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat right -24px;
+}
+
+.x-box-tl, .x-box-bl {
+	padding-left: 8px;
+	overflow: hidden;
+}
+
+.x-box-tr, .x-box-br {
+	padding-right: 8px;
+	overflow: hidden;
+}
+
+.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr {
+	background-image: url(/static/images/extjs/default/box/corners-blue.gif);
+}
+
+.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc {
+	background-image: url(/static/images/extjs/default/box/tb-blue.gif);
+}
+
+.x-box-blue .x-box-mc {
+	background-color: #c3daf9;
+}
+
+.x-box-blue .x-box-mc h3 {
+	color: #17385b;
+}
+
+.x-box-blue .x-box-ml {
+	background-image: url(/static/images/extjs/default/box/l-blue.gif);
+}
+
+.x-box-blue .x-box-mr {
+	background-image: url(/static/images/extjs/default/box/r-blue.gif);
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/button.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/button.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,154 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-btn{
+	font:normal 11px tahoma, verdana, helvetica;
+	cursor:pointer;
+	white-space: nowrap;
+}
+.x-btn button{
+    border:0 none;
+    background:transparent;
+    font:normal 11px tahoma,verdana,helvetica;
+    padding-left:3px;
+    padding-right:3px;
+    cursor:pointer;
+    margin:0;
+    overflow:visible;
+    width:auto;
+    -moz-outline:0 none;
+    outline:0 none;
+}
+* html .ext-ie .x-btn button {
+    width:1px;
+}
+.ext-gecko .x-btn button {
+    padding-left:0;
+    padding-right:0;
+}
+/*
+ Predefined css class for buttons with only icon. Add this class (x-btn-icon) and a class with a background-image
+ to your button for a button with just an icon.
+ e.g.
+ .my-class .x-btn-text { background-image: url(foo.gif); }
+ */
+ 
+.x-btn-icon .x-btn-center .x-btn-text{
+	background-position: center;
+	background-repeat: no-repeat;
+	height: 16px;
+	width: 16px;
+	cursor:pointer;
+	white-space: nowrap;
+    padding:0;
+}
+.x-btn-icon .x-btn-center{
+	padding:1px;
+}
+.x-btn em {
+    font-style:normal;
+    font-weight:normal;
+}
+/*
+ Button class for icon and text. Add this class (x-btn-text-icon) and a class with a background-image
+ to your button for both text and icon. 
+*/
+
+.x-btn-text-icon .x-btn-center .x-btn-text{
+	background-position: 0 2px;
+	background-repeat: no-repeat;
+	padding-left:18px;
+	padding-top:3px;
+	padding-bottom:3px;
+    padding-right:0;
+}
+
+.x-btn-left, .x-btn-right{
+	font-size:1px;
+    line-height:1px;
+}
+.x-btn-left{
+	width:3px;
+	height:21px;
+	background:url(/static/images/extjs/default/basic-dialog/btn-sprite.gif) no-repeat 0 0;
+}
+.x-btn-right{
+	width:3px;
+	height:21px;
+	background:url(/static/images/extjs/default/basic-dialog/btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-btn-left i, .x-btn-right i{
+	display:block;
+    width:3px;
+    overflow:hidden;
+    font-size:1px;
+    line-height:1px;
+}
+.x-btn-center{
+	background:url(/static/images/extjs/default/basic-dialog/btn-sprite.gif) repeat-x 0 -42px;
+	vertical-align: middle;
+	text-align:center;
+	padding:0 5px;
+	cursor:pointer;
+	white-space:nowrap;
+}
+.x-btn-focus .x-btn-left{
+	background-position:0 -126px;
+}
+.x-btn-focus .x-btn-right{
+	background-position:0 -147px;
+}
+.x-btn-focus .x-btn-center{
+	background-position:0 -168px;
+}
+.x-btn-over .x-btn-left{
+	background-position:0 -63px;
+}
+.x-btn-over .x-btn-right{
+	background-position:0 -84px;
+}
+.x-btn-over .x-btn-center{
+	background-position:0 -105px;
+}
+.x-btn-click .x-btn-center, .x-btn-menu-active .x-btn-center{
+	background-position:0 -126px;
+}
+.x-btn-disabled *{
+	color:gray !important;
+	cursor:default !important;
+}
+.x-btn-menu-text-wrap .x-btn-center {
+	padding:0 3px;
+}
+.ext-gecko .x-btn-menu-text-wrap .x-btn-center {
+	padding:0 1px;
+}
+.x-btn-menu-arrow-wrap .x-btn-center {
+    padding:0;
+}
+.x-btn-menu-arrow-wrap .x-btn-center button {
+	width:12px !important;
+    height:21px;
+    padding:0 !important;
+    display:block;
+    background:transparent url(/static/images/extjs/default/basic-dialog/btn-arrow.gif) no-repeat left 3px;
+}
+.x-btn-with-menu  .x-btn-center {
+    padding-right:2px !important;
+}
+.x-btn-with-menu  .x-btn-center em {
+    display:block;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat right 0;
+	padding-right:10px;
+}
+
+.x-btn-text-icon .x-btn-with-menu .x-btn-center em {
+    display:block;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat right 3px;
+	padding-right:10px;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/combo.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/combo.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,46 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-combo-list {
+    border:1px solid #98c0f4;
+    background:#ddecfe;
+    zoom:1;
+    overflow:hidden;
+}
+.x-combo-list-inner {
+    overflow:auto;
+    background:white;
+    position:relative; /* for calculating scroll offsets */
+}
+.x-combo-list-hd {
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+    color:#15428b;
+    background-image: url(/static/images/extjs/default/layout/panel-title-light-bg.gif);
+    border-bottom:1px solid #98c0f4;
+    padding:3px;
+}
+.x-resizable-pinned .x-combo-list-inner {
+    border-bottom:1px solid #98c0f4;
+}
+.x-combo-list-item {
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+    padding:2px;
+    border:1px solid #fff;
+    zoom:1;
+    white-space: nowrap;
+    overflow:hidden;
+    text-overflow: ellipsis;
+}
+.x-combo-list .x-combo-selected{
+	background-color: #c3daf9 !important;
+    cursor:pointer;
+    border:1px solid #336699;
+}
+.x-combo-noedit{
+    cursor:pointer;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/core.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/core.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,271 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.ext-el-mask {
+    z-index: 20000;
+    position: absolute;
+    top: 0;
+    left: 0;
+    -moz-opacity: 0.5;
+    opacity: .50;
+    filter: alpha(opacity=50);
+    background-color: #CCC;
+    width: 100%;
+    height: 100%;
+    zoom: 1;
+}
+.ext-el-mask-msg {
+    z-index: 20001;
+    position: absolute;
+    top: 0;
+    left: 0;
+    border:1px solid #6593cf;
+    background: #c3daf9 url(/static/images/extjs/default/box/tb-blue.gif) repeat-x 0 -16px;
+    padding:2px;
+}
+.ext-el-mask-msg div {
+    padding:5px 10px 5px 10px;
+    background: #eee;
+    border:1px solid #a3bad9;
+    color:#333;
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+    cursor:wait;
+}
+
+
+.x-mask-loading div {
+    padding:5px 10px 5px 25px;
+    background: #eee url( '/static/images/extjs/default/grid/loading.gif' ) no-repeat 5px 5px;
+    line-height: 16px;
+}
+
+/* class for hiding elements without using display:none */
+.x-hidden {
+    position:absolute;
+    left:-2000px;
+    top:-2000px;
+    visibility:hidden;
+}
+
+.x-masked {
+    overflow: hidden !important;
+}
+
+.x-masked select, .x-masked object, .x-masked embed {
+    visibility: hidden;
+}
+
+.x-layer {
+    visibility: hidden;
+}
+
+.x-unselectable, .x-unselectable * {
+    -moz-user-select: none;
+    -khtml-user-select: none;
+}
+
+.x-repaint {
+    zoom: 1;
+    background-color: transparent;
+    -moz-outline: none;
+}
+
+.x-item-disabled {
+    color: gray;
+    cursor: default;
+    opacity: .6;
+    -moz-opacity: .6;
+    filter: alpha(opacity=60);
+}
+
+.x-item-disabled * {
+    color: gray;
+    cursor: default !important;
+}
+
+.x-splitbar-proxy {
+    position: absolute;
+    visibility: hidden;
+    z-index: 20001;
+    background: #aaa;
+    zoom: 1;
+    line-height: 1px;
+    font-size: 1px;
+    overflow: hidden;
+}
+
+.x-splitbar-h, .x-splitbar-proxy-h {
+    cursor: e-resize;
+    cursor: col-resize;
+}
+
+.x-splitbar-v, .x-splitbar-proxy-v {
+    cursor: s-resize;
+    cursor: row-resize;
+}
+
+.x-color-palette {
+    width: 150px;
+    height: 92px;
+}
+
+.x-color-palette a {
+    border: 1px solid #fff;
+    float: left;
+    padding: 2px;
+    text-decoration: none;
+    -moz-outline: 0 none;
+    outline: 0 none;
+}
+
+.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel {
+    border: 1px solid #8BB8F3;
+    background: #deecfd;
+}
+
+.x-color-palette em {
+    display: block;
+    border: 1px solid #ACA899;
+}
+
+.x-color-palette em span {
+    cursor: pointer;
+    display: block;
+    height: 10px;
+    line-height: 10px;
+    width: 10px;
+}
+
+.x-shadow {
+    display: none;
+    position: absolute;
+    overflow: hidden;
+}
+
+.x-shadow * {
+    overflow: hidden;
+}
+
+.x-shadow * {
+    padding: 0;
+    border: 0;
+    margin: 0;
+    clear: none;
+    zoom: 1;
+}
+
+/* top  bottom */
+.x-shadow .xstc, .x-shadow .xsbc {
+    height: 6px;
+    float: left;
+}
+
+/* corners */
+.x-shadow .xstl, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbr {
+    width: 6px;
+    height: 6px;
+    float: left;
+}
+
+/* sides */
+.x-shadow .xsc {
+    width: 100%;
+}
+
+.x-shadow .xsml, .x-shadow .xsmr {
+    width: 6px;
+    float: left;
+    height: 100%;
+}
+
+.x-shadow .xsmc {
+    float: left;
+    height: 100%;
+    background: #333333;
+    opacity: .35;
+    -moz-opacity: .35;
+    filter: alpha(opacity=25);
+}
+
+.x-shadow .xst, .x-shadow .xsb {
+    height: 6px;
+    overflow: hidden;
+    width: 100%;
+}
+
+.x-shadow .xsml {
+    background: transparent url( /static/images/extjs/default/shadow-lr.png ) repeat-y 0 0;
+}
+
+.x-shadow .xsmr {
+    background: transparent url( /static/images/extjs/default/shadow-lr.png ) repeat-y -6px 0;
+}
+
+.x-shadow .xstl {
+    background: transparent url( /static/images/extjs/default/shadow.png ) no-repeat 0 0;
+}
+
+.x-shadow .xstc {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -30px;
+}
+
+.x-shadow .xstr {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -18px;
+}
+
+.x-shadow .xsbl {
+    background: transparent url( /static/images/extjs/default/shadow.png ) no-repeat 0 -12px;
+}
+
+.x-shadow .xsbc {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -36px;
+}
+
+.x-shadow .xsbr {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -6px;
+}
+
+.loading-indicator {
+    font-size: 11px;
+    background-image: url( '/static/images/extjs/default/grid/loading.gif' );
+    background-repeat: no-repeat;
+    background-position: left;
+    padding-left: 20px;
+    line-height: 16px;
+    margin: 3px;
+}
+
+.x-text-resize {
+    position: absolute;
+    left: -1000px;
+    top: -1000px;
+    visibility: hidden;
+    zoom: 1;
+}
+
+.x-drag-overlay {
+    width: 100%;
+    height: 100%;
+    display: none;
+    position: absolute;
+    left: 0;
+    top: 0;
+    background: white;
+    z-index: 20000;
+    -moz-opacity: 0;
+    opacity: 0;
+    filter: alpha(opacity=0);
+}
+
+.x-clear {
+    clear:both;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/date-picker.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/date-picker.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,155 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-date-picker {
+    border: 1px solid #1b376c;
+    border-top:0 none;
+    background:#fff;
+}
+.x-date-picker a {
+    -moz-outline:0 none;
+    outline:0 none;
+}
+.x-date-inner, .x-date-inner td, .x-date-inner th{
+    border-collapse:separate;
+}
+.x-date-middle,.x-date-left,.x-date-right {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) repeat-x 0 -83px;
+	color:#FFF;
+	font:bold 11px "sans serif", tahoma, verdana, helvetica;
+	overflow:hidden;
+}
+
+.x-date-middle .x-btn-left,.x-date-middle .x-btn-center,.x-date-middle .x-btn-right{
+	background:transparent !important;
+    vertical-align:middle;
+}
+.x-date-middle .x-btn .x-btn-text {
+    color:#fff;
+}
+.x-date-middle .x-btn-with-menu  .x-btn-center em {
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow-light.gif) no-repeat right 0;
+}
+.x-date-right, .x-date-left {
+    width:18px;
+}
+.x-date-right{
+    text-align:right;
+}
+.x-date-middle {
+    padding-top:2px;padding-bottom:2px;
+}
+.x-date-right a, .x-date-left a{
+    display:block;
+    width:16px;
+	height:16px;
+	background-position: center;
+	background-repeat: no-repeat;
+	cursor:pointer;
+    -moz-opacity: 0.6;
+    opacity:.6;
+    filter: alpha(opacity=60);
+}
+.x-date-right a:hover, .x-date-left a:hover{
+    -moz-opacity: 1;
+    opacity:1;
+    filter: alpha(opacity=100);
+}
+.x-date-right a {
+    background-image: url(/static/images/extjs/default/shared/right-btn.gif);
+    margin-right:2px;
+}
+.x-date-left a{
+	background-image: url(/static/images/extjs/default/shared/left-btn.gif);
+    margin-left:2px;
+}
+table.x-date-inner {
+    width:100%;
+    table-layout:fixed;
+}
+.x-date-inner th {
+    width:25px;
+}
+.x-date-inner th {
+    background: #c3daf9;
+    text-align:right !important;
+	border-bottom: 1px solid #a3bad9;
+    font:normal 10px arial, helvetica,tahoma,sans-serif;
+	color:#233d6d;
+	cursor:default;
+    padding:0;
+    border-collapse:separate;
+}
+.x-date-inner th span {
+    display:block;
+    padding:2px;
+    padding-right:7px;
+}
+.x-date-inner td {
+    border: 1px solid #fff;
+	text-align:right;
+    padding:0;
+}
+.x-date-inner a {
+    padding:2px 5px;
+    display:block;
+    font:normal 11px arial, helvetica,tahoma,sans-serif;
+	text-decoration:none;
+    color:black;
+    text-align:right;
+    zoom:1;
+}
+.x-date-inner .x-date-active{
+	cursor:pointer;
+	color:black;
+}
+.x-date-inner .x-date-selected a{
+	background: #ddecfe;
+	border: 1px solid #a3bad9;
+    padding:1px 4px;
+}
+.x-date-inner .x-date-today a{
+	border: 1px solid darkred;
+    padding:1px 4px;
+}
+.x-date-inner .x-date-selected span{
+    font-weight:bold;
+}
+.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a {
+	color:#aaaaaa;
+}
+.x-date-bottom {
+    padding:4px;
+    border-top: 1px solid #a3bad9;
+    background: #c3daf9;
+}
+
+.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{
+    text-decoration:none;
+    color:black;
+    background: #ddecfe;
+}
+
+.x-date-inner .x-date-disabled a {
+	cursor:default;
+	background:#eeeeee;
+	color:#bbbbbb;
+}
+.x-date-mmenu{
+    background:#eeeeee !important;
+}
+.x-date-mmenu .x-menu-item {
+	font-size:10px;
+	padding:1px 24px 1px 4px;
+	white-space: nowrap;
+	color:#000;
+}
+.x-date-mmenu .x-menu-item .x-menu-item-icon {
+    width:10px;height:10px;margin-right:5px;
+    background-position:center -4px !important;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/dd.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/dd.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,61 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-dd-drag-proxy{
+	position:absolute;
+	left:0;top:0;
+	visibility:hidden;
+	z-index:15000;
+}
+.x-dd-drag-ghost{
+	color: black;
+	font: normal 11px arial, helvetica, sans-serif;
+	-moz-opacity: 0.85;
+   opacity:.85;
+   filter: alpha(opacity=85);
+	border-top:1px solid #dddddd;
+	border-left:1px solid #dddddd;
+	border-right:1px solid #bbbbbb;
+	border-bottom:1px solid #bbbbbb;
+	padding:3px;
+	padding-left:20px;
+	background-color:white;
+	white-space:nowrap;
+}
+.x-dd-drag-repair .x-dd-drag-ghost{
+	-moz-opacity: 0.4;
+   opacity:.4;
+   filter: alpha(opacity=40);
+	border:0 none;
+	padding:0;
+	background-color:transparent;
+}
+.x-dd-drag-repair .x-dd-drop-icon{
+	visibility:hidden;
+}
+.x-dd-drop-icon{
+  position:absolute;
+	top:3px;
+	left:3px;
+	display:block;
+	width:16px;
+	height:16px;
+	background-color:transparent;
+	background-position: center;
+	background-repeat: no-repeat;
+	z-index:1;
+}
+.x-dd-drop-nodrop .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/dd/drop-no.gif);
+}
+.x-dd-drop-ok .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/dd/drop-yes.gif);
+}
+.x-dd-drop-ok-add .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/dd/drop-add.gif);
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/debug.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/debug.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,55 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+#x-debug-browser .x-tree .x-tree-node a span {
+    color:#222297;
+    font-size:12px;
+    padding-top:2px;
+    font-family:"courier","courier new";
+    line-height:18px;
+}
+#x-debug-browser .x-tree a i {
+    color:#FF4545;
+    font-style:normal;
+}
+#x-debug-browser .x-tree a em {
+    color:#999;
+}
+#x-debug-browser .x-tree .x-tree-node .x-tree-selected a span{
+    background:#c3daf9;
+}
+#x-debug-browser pre, .x-debug-browser pre xmp {
+    font:normal 11px tahoma, arial, helvetica, sans-serif !important;
+    white-space: -moz-pre-wrap;
+    white-space: -pre-wrap;
+    white-space: -o-pre-wrap;
+    word-wrap: break-word;
+}
+#x-debug-browser pre {
+    display:block;
+    padding:5px !important;
+    border-bottom:1px solid #eeeeee !important;
+}
+#x-debug-browser pre xmp {
+    padding:0 !important;
+    margin:0 !important;
+}
+#x-debug-console .x-layout-panel-center, #x-debug-inspector .x-layout-panel-center {
+      border-right:1px solid #98c0f4;
+}
+#x-debug-console textarea {
+    border: 0 none;
+    font-size:12px;
+    font-family:"courier","courier new";
+    padding-top:4px;
+    padding-left:4px;
+}
+.x-debug-frame {
+    background:#eeeeee;
+    border:1px dashed #aaaaaa;
+}
\ No newline at end of file

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ext-all.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ext-all.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,2711 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}
+.ext-el-mask {
+    z-index: 20000;
+    position: absolute;
+    top: 0;
+    left: 0;
+    -moz-opacity: 0.5;
+    opacity: .50;
+    filter: alpha(opacity=50);
+    background-color: #CCC;
+    width: 100%;
+    height: 100%;
+    zoom: 1;
+}
+.ext-el-mask-msg {
+    z-index: 20001;
+    position: absolute;
+    top: 0;
+    left: 0;
+    border:1px solid #6593cf;
+    background: #c3daf9 url(/static/images/extjs/default/box/tb-blue.gif) repeat-x 0 -16px;
+    padding:2px;
+}
+.ext-el-mask-msg div {
+    padding:5px 10px 5px 10px;
+    background: #eee;
+    border:1px solid #a3bad9;
+    color:#333;
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+    cursor:wait;
+}
+
+
+.x-mask-loading div {
+    padding:5px 10px 5px 25px;
+    background: #eee url( '/static/images/extjs/default/grid/loading.gif' ) no-repeat 5px 5px;
+    line-height: 16px;
+}
+
+
+.x-hidden {
+    position:absolute;
+    left:-2000px;
+    top:-2000px;
+    visibility:hidden;
+}
+
+.x-masked {
+    overflow: hidden !important;
+}
+
+.x-masked select, .x-masked object, .x-masked embed {
+    visibility: hidden;
+}
+
+.x-layer {
+    visibility: hidden;
+}
+
+.x-unselectable, .x-unselectable * {
+    -moz-user-select: none;
+    -khtml-user-select: none;
+}
+
+.x-repaint {
+    zoom: 1;
+    background-color: transparent;
+    -moz-outline: none;
+}
+
+.x-item-disabled {
+    color: gray;
+    cursor: default;
+    opacity: .6;
+    -moz-opacity: .6;
+    filter: alpha(opacity=60);
+}
+
+.x-item-disabled * {
+    color: gray;
+    cursor: default !important;
+}
+
+.x-splitbar-proxy {
+    position: absolute;
+    visibility: hidden;
+    z-index: 20001;
+    background: #aaa;
+    zoom: 1;
+    line-height: 1px;
+    font-size: 1px;
+    overflow: hidden;
+}
+
+.x-splitbar-h, .x-splitbar-proxy-h {
+    cursor: e-resize;
+    cursor: col-resize;
+}
+
+.x-splitbar-v, .x-splitbar-proxy-v {
+    cursor: s-resize;
+    cursor: row-resize;
+}
+
+.x-color-palette {
+    width: 150px;
+    height: 92px;
+}
+
+.x-color-palette a {
+    border: 1px solid #fff;
+    float: left;
+    padding: 2px;
+    text-decoration: none;
+    -moz-outline: 0 none;
+    outline: 0 none;
+}
+
+.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel {
+    border: 1px solid #8BB8F3;
+    background: #deecfd;
+}
+
+.x-color-palette em {
+    display: block;
+    border: 1px solid #ACA899;
+}
+
+.x-color-palette em span {
+    cursor: pointer;
+    display: block;
+    height: 10px;
+    line-height: 10px;
+    width: 10px;
+}
+
+.x-shadow {
+    display: none;
+    position: absolute;
+    overflow: hidden;
+}
+
+.x-shadow * {
+    overflow: hidden;
+}
+
+.x-shadow * {
+    padding: 0;
+    border: 0;
+    margin: 0;
+    clear: none;
+    zoom: 1;
+}
+
+
+.x-shadow .xstc, .x-shadow .xsbc {
+    height: 6px;
+    float: left;
+}
+
+
+.x-shadow .xstl, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbr {
+    width: 6px;
+    height: 6px;
+    float: left;
+}
+
+
+.x-shadow .xsc {
+    width: 100%;
+}
+
+.x-shadow .xsml, .x-shadow .xsmr {
+    width: 6px;
+    float: left;
+    height: 100%;
+}
+
+.x-shadow .xsmc {
+    float: left;
+    height: 100%;
+    background: #333333;
+    opacity: .35;
+    -moz-opacity: .35;
+    filter: alpha(opacity=25);
+}
+
+.x-shadow .xst, .x-shadow .xsb {
+    height: 6px;
+    overflow: hidden;
+    width: 100%;
+}
+
+.x-shadow .xsml {
+    background: transparent url( /static/images/extjs/default/shadow-lr.png ) repeat-y 0 0;
+}
+
+.x-shadow .xsmr {
+    background: transparent url( /static/images/extjs/default/shadow-lr.png ) repeat-y -6px 0;
+}
+
+.x-shadow .xstl {
+    background: transparent url( /static/images/extjs/default/shadow.png ) no-repeat 0 0;
+}
+
+.x-shadow .xstc {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -30px;
+}
+
+.x-shadow .xstr {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -18px;
+}
+
+.x-shadow .xsbl {
+    background: transparent url( /static/images/extjs/default/shadow.png ) no-repeat 0 -12px;
+}
+
+.x-shadow .xsbc {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -36px;
+}
+
+.x-shadow .xsbr {
+    background: transparent url( /static/images/extjs/default/shadow.png ) repeat-x 0 -6px;
+}
+
+.loading-indicator {
+    font-size: 11px;
+    background-image: url( '/static/images/extjs/default/grid/loading.gif' );
+    background-repeat: no-repeat;
+    background-position: left;
+    padding-left: 20px;
+    line-height: 16px;
+    margin: 3px;
+}
+
+.x-text-resize {
+    position: absolute;
+    left: -1000px;
+    top: -1000px;
+    visibility: hidden;
+    zoom: 1;
+}
+
+.x-drag-overlay {
+    width: 100%;
+    height: 100%;
+    display: none;
+    position: absolute;
+    left: 0;
+    top: 0;
+    background: white;
+    z-index: 20000;
+    -moz-opacity: 0;
+    opacity: 0;
+    filter: alpha(opacity=0);
+}
+
+.x-clear {
+    clear:both;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+
+.x-tabs-wrap {
+	border-bottom:1px solid #6593cf;
+	padding-top:2px;
+}
+.x-tabs-strip-wrap{
+	width:100%;	
+}
+.x-tabs-wrap table{
+	position:relative;
+	top:0; left:0;
+}
+.x-tabs-strip td{
+	padding:0;
+	padding-left:2px;
+}
+.x-tabs-strip a, .x-tabs-strip span, .x-tabs-strip em {
+	display:block;
+}
+.x-tabs-strip a {
+	text-decoration:none !important;
+	-moz-outline: none;
+	outline: none;
+	cursor:pointer;
+}
+.x-tabs-strip .x-tabs-text {
+	font:bold 11px tahoma,arial,helvetica;
+	color:#666;
+	overflow:hidden;
+	white-space: nowrap;
+	cursor:pointer;
+	text-overflow: ellipsis;
+}
+.x-tabs-strip .on .x-tabs-text {
+	cursor:default;
+	color:#083772;
+}
+.x-tabs-strip .disabled .x-tabs-text {
+	cursor:default;
+	color:#aaaaaa;
+}
+.x-tabs-strip .x-tabs-inner {
+	 padding:4px 10px;	
+}
+
+.x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat right 0;
+}
+.x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat 0 -100px;
+}
+.x-tabs-strip .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat right -50px;
+}
+.x-tabs-strip .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat 0 -150px;
+}
+
+.x-tabs-strip  a {
+	position:relative;
+	top:1px; left:0;
+}
+.x-tabs-strip .on a {
+	position:relative;
+}
+.x-tabs-strip .on .x-tabs-inner {
+	padding-bottom:5px;
+}
+
+.x-tabs-strip .x-tabs-closable .x-tabs-inner{
+	padding-right:22px;
+	position:relative;
+}
+.x-tabs-strip .x-tabs-closable .close-icon{
+	line-height: 1px;
+	font-size:1px;
+	background-image:url(/static/images/extjs/default/layout/tab-close.gif);
+	display:block;
+	position:absolute;
+	right:5px;top:4px;
+	width:11px;height:11px;
+	cursor:pointer;
+}
+.x-tabs-strip .on .close-icon{
+	background-image:url(/static/images/extjs/default/layout/tab-close-on.gif);
+}
+.x-tabs-strip .x-tabs-closable .close-over{
+	background-image:url(/static/images/extjs/default/layout/tab-close-on.gif);
+}
+.x-tabs-body {
+    border:1px solid #6593cf;
+    border-top:0 none;
+}
+.x-tabs-bottom .x-tabs-wrap {
+	border-top:1px solid #6593cf;
+	border-bottom:0 none;
+	padding-top:0;
+	padding-bottom:2px;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-inactive-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-inactive-left-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-left-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip  a {
+	position:relative;
+	top:0; left:0;
+}
+.x-tabs-bottom .x-tabs-strip .on a {
+	margin-top:-1px;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-inner {
+	padding-top:5px;
+}
+
+.x-tabs-bottom .x-tabs-body {
+    border:1px solid #6593cf;
+    border-bottom:0 none;
+}
+
+
+
+.x-form-field{
+    margin: 0 0 0 0;
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+
+.x-form-text, textarea.x-form-field{
+    padding: 1px 3px;
+    background:#fff url(/static/images/extjs/default/form/text-bg.gif) repeat-x 0 0;
+    border: 1px solid #B5B8C8;
+}
+.x-form-text {
+    height:22px;
+    line-height:18px;
+    vertical-align:middle;
+}
+.ext-ie .x-form-text {
+    margin-top:-1px; 
+    margin-bottom:-1px;
+    height:22px; 
+    line-height:18px;
+}
+.ext-strict .x-form-text {
+    height:18px;
+}
+.ext-safari .x-form-text {
+    height:20px; 
+}
+.ext-gecko .x-form-text {
+    padding-top:2px; 
+    padding-bottom:0;
+}
+
+
+.x-form-select-one {
+    height:20px;
+    line-height:18px;
+    vertical-align:middle;
+    background-color:#fff; 
+    border: 1px solid #B5B8C8;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.x-form-field-wrap {
+    position:relative;
+    zoom:1;
+    white-space: nowrap;
+}
+
+.x-editor .x-form-check-wrap {
+    background:#fff;
+}
+.x-form-field-wrap .x-form-trigger{
+    width:17px;
+    height:21px;
+    border:0;
+    background:transparent url(/static/images/extjs/default/form/trigger.gif) no-repeat 0 0;
+    cursor:pointer;
+    border-bottom: 1px solid #B5B8C8;
+    position:absolute;
+    top:0;
+}
+.ext-safari .x-form-field-wrap .x-form-trigger{
+    height:19px; 
+}
+.x-form-field-wrap .x-form-trigger-over{
+    background-position:-17px 0;
+}
+.x-form-field-wrap .x-form-trigger-click{
+    background-position:-34px 0;
+}
+.x-item-disabled .x-form-trigger-over{
+    background-position:0 0 !important;
+}
+.x-item-disabled .x-form-trigger-click{
+    background-position:0 0 !important;
+}
+.x-form-field-wrap .x-form-date-trigger{
+    background:transparent url(/static/images/extjs/default/form/date-trigger.gif) no-repeat 0 0;
+    cursor:pointer;
+}
+.ext-safari .x-form-field-wrap .x-form-date-trigger{
+    right:0;
+}
+
+
+.x-form-focus{
+	border: 1px solid #7eadd9;
+}
+
+
+.x-form-invalid{
+	background:#fff url(/static/images/extjs/default/grid/invalid_line.gif) repeat-x bottom;
+	border: 1px solid #dd7870;
+}
+.ext-safari .x-form-invalid{
+	background-color:#ffeeee;
+	border: 1px solid #ff7870;
+}
+
+
+
+.x-editor {
+    visibility:hidden;
+    padding:0;
+    margin:0;
+}
+.x-form-check-wrap {
+    line-height:18px;
+}
+.ext-ie .x-form-check-wrap input {
+    width:15px;
+    height:15px;
+}
+.x-editor .x-form-check-wrap {
+    padding:3px;
+}
+.x-editor .x-form-checkbox {
+    height:13px;
+    border: 0 none;
+}
+
+.x-form-grow-sizer {
+	font:normal 12px tahoma, arial, helvetica, sans-serif;
+    left: -10000px;
+	padding: 8px 3px;
+    position: absolute;
+    visibility:hidden;
+    top: -10000px;
+	white-space: pre-wrap;
+    white-space: -moz-pre-wrap;
+    white-space: -pre-wrap;
+    white-space: -o-pre-wrap;
+    word-wrap: break-word;
+    zoom:1;
+}
+
+
+
+.x-form-item {
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+    display:block;
+    margin-bottom:4px;
+}
+
+.x-form-item label {
+    display:block;
+    float:left;
+    width:100px;
+    padding:3px;
+    padding-left:0;
+    clear:left;
+}
+
+.x-form-element {
+    padding-left:105px;
+    position:relative;
+}
+
+.x-form-invalid-msg {
+    color:#ee0000;
+    padding:2px;
+    padding-left:18px;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+    background: transparent url(/static/images/extjs/default/shared/warning.gif) no-repeat 0 2px;
+    line-height:16px;
+    width:200px;
+}
+
+.x-form-label-right label {
+   text-align:right;
+}
+
+.x-form-label-top .x-form-item label {
+    width:auto;
+    float:none;
+    clear:none;
+    display:inline;
+    margin-bottom:4px;
+}
+.x-form-label-top .x-form-element {
+    padding-left:0;
+    padding-top:4px;
+}
+.x-form-label-top .x-form-item {
+    padding-bottom:4px;
+}
+.x-form fieldset {
+    border:1px solid #B5B8C8;
+    padding:10px 10px 5px 10px;
+    margin-bottom:10px;
+}
+.x-form fieldset legend {
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+    color:#15428b;
+}
+.ext-ie .x-form fieldset legend {
+    margin-bottom:10px;
+}
+.x-form-empty-field {
+    color:gray;
+}
+
+.x-small-editor .x-form-field {
+    font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.x-small-editor .x-form-text {
+    height:20px;
+    line-height:16px;
+    vertical-align:middle;
+}
+.ext-ie .x-small-editor .x-form-text {
+    margin-top:-1px !important; 
+    margin-bottom:-1px !important;
+    height:20px !important; 
+    line-height:16px !important;
+}
+.ext-strict .x-small-editor .x-form-text {
+    height:16px !important;
+}
+.ext-safari .x-small-editor .x-form-field {
+    
+    font:normal 12px arial, tahoma, helvetica, sans-serif;
+}
+.ext-ie .x-small-editor .x-form-text {
+    height:20px;
+    line-height:16px;
+}
+.ext-border-box .x-small-editor .x-form-text {
+    height:20px;
+}
+
+.x-small-editor .x-form-select-one {
+    height:20px;
+    line-height:16px;
+    vertical-align:middle;
+}
+.x-small-editor .x-form-num-field {
+    text-align:right;
+}
+.x-small-editor .x-form-field-wrap .x-form-trigger{
+    height:19px;
+}
+
+
+.x-form-clear {
+    clear:both;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+.x-form-clear-left {
+    clear:left;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+
+.x-form-cb-label {
+    width:'auto' !important;
+    float:none !important;
+    clear:none !important;
+    display:inline !important;
+    margin-left:4px;
+}
+
+.x-form-column {
+    float:left;
+    padding:0;
+    margin:0;
+    width:48%;
+    overflow:hidden;
+    zoom:1;
+}
+
+
+.x-form .x-form-btns-ct .x-btn{
+	float:right;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns td {
+	border:0;
+	padding:0;
+}
+.x-form .x-form-btns-ct .x-form-btns-right table{
+	float:right;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns-left table{
+	float:left;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns-center{
+	text-align:center; 
+}
+.x-form .x-form-btns-ct .x-form-btns-center table{
+	margin:0 auto; 
+}
+.x-form .x-form-btns-ct table td.x-form-btn-td{
+	padding:3px;
+}
+
+.x-form-invalid-icon {
+    width:16px;
+    height:18px;
+    visibility:hidden;
+    position:absolute;
+    left:0;
+    top:0;
+    display:block;
+    background:transparent url(/static/images/extjs/default/form/exclamation.gif) no-repeat 0 2px;
+}
+.x-btn{
+	font:normal 11px tahoma, verdana, helvetica;
+	cursor:pointer;
+	white-space: nowrap;
+}
+.x-btn button{
+    border:0 none;
+    background:transparent;
+    font:normal 11px tahoma,verdana,helvetica;
+    padding-left:3px;
+    padding-right:3px;
+    cursor:pointer;
+    margin:0;
+    overflow:visible;
+    width:auto;
+    -moz-outline:0 none;
+    outline:0 none;
+}
+* html .ext-ie .x-btn button {
+    width:1px;
+}
+.ext-gecko .x-btn button {
+    padding-left:0;
+    padding-right:0;
+}
+
+ 
+.x-btn-icon .x-btn-center .x-btn-text{
+	background-position: center;
+	background-repeat: no-repeat;
+	height: 16px;
+	width: 16px;
+	cursor:pointer;
+	white-space: nowrap;
+    padding:0;
+}
+.x-btn-icon .x-btn-center{
+	padding:1px;
+}
+.x-btn em {
+    font-style:normal;
+    font-weight:normal;
+}
+
+
+.x-btn-text-icon .x-btn-center .x-btn-text{
+	background-position: 0 2px;
+	background-repeat: no-repeat;
+	padding-left:18px;
+	padding-top:3px;
+	padding-bottom:3px;
+    padding-right:0;
+}
+
+.x-btn-left, .x-btn-right{
+	font-size:1px;
+    line-height:1px;
+}
+.x-btn-left{
+	width:3px;
+	height:21px;
+	background:url(/static/images/extjs/default/basic-dialog/btn-sprite.gif) no-repeat 0 0;
+}
+.x-btn-right{
+	width:3px;
+	height:21px;
+	background:url(/static/images/extjs/default/basic-dialog/btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-btn-left i, .x-btn-right i{
+	display:block;
+    width:3px;
+    overflow:hidden;
+    font-size:1px;
+    line-height:1px;
+}
+.x-btn-center{
+	background:url(/static/images/extjs/default/basic-dialog/btn-sprite.gif) repeat-x 0 -42px;
+	vertical-align: middle;
+	text-align:center;
+	padding:0 5px;
+	cursor:pointer;
+	white-space:nowrap;
+}
+.x-btn-focus .x-btn-left{
+	background-position:0 -126px;
+}
+.x-btn-focus .x-btn-right{
+	background-position:0 -147px;
+}
+.x-btn-focus .x-btn-center{
+	background-position:0 -168px;
+}
+.x-btn-over .x-btn-left{
+	background-position:0 -63px;
+}
+.x-btn-over .x-btn-right{
+	background-position:0 -84px;
+}
+.x-btn-over .x-btn-center{
+	background-position:0 -105px;
+}
+.x-btn-click .x-btn-center, .x-btn-menu-active .x-btn-center{
+	background-position:0 -126px;
+}
+.x-btn-disabled *{
+	color:gray !important;
+	cursor:default !important;
+}
+.x-btn-menu-text-wrap .x-btn-center {
+	padding:0 3px;
+}
+.ext-gecko .x-btn-menu-text-wrap .x-btn-center {
+	padding:0 1px;
+}
+.x-btn-menu-arrow-wrap .x-btn-center {
+    padding:0;
+}
+.x-btn-menu-arrow-wrap .x-btn-center button {
+	width:12px !important;
+    height:21px;
+    padding:0 !important;
+    display:block;
+    background:transparent url(/static/images/extjs/default/basic-dialog/btn-arrow.gif) no-repeat left 3px;
+}
+.x-btn-with-menu  .x-btn-center {
+    padding-right:2px !important;
+}
+.x-btn-with-menu  .x-btn-center em {
+    display:block;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat right 0;
+	padding-right:10px;
+}
+
+.x-btn-text-icon .x-btn-with-menu .x-btn-center em {
+    display:block;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat right 3px;
+	padding-right:10px;
+}
+.x-toolbar{
+	border: 1px solid;
+    border-color:#eaf0f7 #eaf0f7 #a9bfd3 #eaf0f7;
+    display: block;
+	padding:2px;
+    background:#d0def0 url(/static/images/extjs/default/layout/panel-title-light-bg.gif) repeat-x;
+}
+.x-toolbar td {
+	vertical-align:middle;
+}
+.mso .x-toolbar, .x-grid-mso .x-toolbar{
+	border: 0 none;
+	background: url(/static/images/extjs/default/grid/mso-hd.gif);
+}
+.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{
+	white-space: nowrap;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-toolbar .x-item-disabled {
+	color:gray;
+	cursor:default;
+	opacity:.6;
+	-moz-opacity:.6;
+	filter:alpha(opacity=60);
+}
+.x-toolbar .x-item-disabled * {
+	color:gray;
+	cursor:default;
+}
+.x-toolbar .x-btn-left{
+	background:none;
+}
+.x-toolbar .x-btn-right{
+	background:none;
+}
+.x-toolbar .x-btn-center{
+	background:none;
+	padding:0 0;
+}
+.x-toolbar .x-btn-menu-text-wrap .x-btn-center button{
+	padding-right:2px;
+}
+.ext-gecko .x-toolbar .x-btn-menu-text-wrap .x-btn-center button{
+	padding-right:0;
+}
+.x-toolbar .x-btn-menu-arrow-wrap .x-btn-center button{
+	padding:0 2px;
+}
+.x-toolbar .x-btn-menu-arrow-wrap .x-btn-center button {
+    width:12px;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat 0 3px;
+}
+.x-toolbar .x-btn-text-icon .x-btn-menu-arrow-wrap .x-btn-center button {
+    width:12px;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat 0 3px;
+}
+.x-toolbar .x-btn-over .x-btn-menu-arrow-wrap .x-btn-center button {
+	background-position: 0 -47px;
+}
+.x-toolbar .x-btn-over .x-btn-left{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 0;
+}
+.x-toolbar .x-btn-over .x-btn-right{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-toolbar .x-btn-over .x-btn-center{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) repeat-x 0 -42px;
+}
+
+.x-toolbar .x-btn-click .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 -63px;
+}
+.x-toolbar .x-btn-click .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 -84px;
+}
+.x-toolbar .x-btn-click .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) repeat-x 0 -105px;
+}
+
+.x-toolbar .ytb-text{
+   padding:2px;
+}
+.x-toolbar .ytb-sep {
+	background-image: url(/static/images/extjs/default/grid/grid-split.gif);
+	background-position: center;
+	background-repeat: no-repeat;
+	display: block;
+	font-size: 1px;
+	height: 16px;
+	width:4px;
+	overflow: hidden;
+	cursor:default;
+	margin: 0 2px 0;
+	border:0;
+}
+.x-toolbar .ytb-spacer {
+    width:2px;
+}
+.mso .x-toolbar .ytb-sep, .x-grid-mso .x-toolbar .ytb-sep{
+	background-image: url(/static/images/extjs/default/grid/grid-blue-split.gif);
+}
+
+
+.ext-ie .x-toolbar .x-form-field-wrap {
+	padding-bottom:1px;
+}
+.ext-ie .x-toolbar .x-form-field-wrap .x-form-trigger {
+	top:1px;
+}
+
+
+
+.x-grid-page-number{
+	width:24px;
+	height:14px;
+}
+.x-grid-page-first .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-first.gif);
+}
+.x-grid-loading .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/done.gif);
+}
+.x-grid-page-last .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-last.gif);
+}
+.x-grid-page-next .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-next.gif);
+}
+.x-grid-page-prev .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-prev.gif);
+}
+.x-item-disabled .x-grid-loading .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/loading.gif);
+}
+.x-item-disabled .x-grid-page-first .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-first-disabled.gif);
+}
+.x-item-disabled .x-grid-page-last .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-last-disabled.gif);
+}
+.x-item-disabled .x-grid-page-next .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-next-disabled.gif);
+}
+.x-item-disabled .x-grid-page-prev .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-prev-disabled.gif);
+}
+.x-paging-info {
+    position:absolute;
+    top:8px;
+    right: 8px;
+    color:#15428b;
+}
+
+.x-resizable-handle {
+    position:absolute;
+    z-index:100;
+    
+    font-size:1px;
+    line-height:6px;
+    overflow:hidden;
+	 background:white;
+	 filter:alpha(opacity=0);
+	 opacity:0;
+	 zoom:1;
+}
+.x-resizable-handle-east{
+    width:6px;
+    cursor:e-resize;
+    right:0;
+    top:0;
+    height:100%;
+}
+.ext-ie .x-resizable-handle-east {
+      margin-right:-1px; 
+}
+.x-resizable-handle-south{
+    width:100%;
+    cursor:s-resize;
+    left:0;
+    bottom:0;
+    height:6px;
+}
+.ext-ie .x-resizable-handle-south {
+     margin-bottom:-1px; 
+}
+.x-resizable-handle-west{
+    width:6px;
+    cursor:w-resize;
+    left:0;
+    top:0;
+    height:100%;
+}
+.x-resizable-handle-north{
+    width:100%;
+    cursor:n-resize;
+    left:0;
+    top:0;
+    height:6px;
+}
+.x-resizable-handle-southeast{
+    width:6px;
+    cursor:se-resize;
+    right:0;
+    bottom:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-northwest{
+    width:6px;
+    cursor:nw-resize;
+    left:0;
+    top:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-northeast{
+    width:6px;
+    cursor:ne-resize;
+    right:0;
+    top:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-southwest{
+    width:6px;
+    cursor:sw-resize;
+    left:0;
+    bottom:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-over .x-resizable-handle, .x-resizable-pinned .x-resizable-handle{
+    filter:alpha(opacity=100);
+	 opacity:1;
+}
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east{
+    background:url(/static/images/extjs/default/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west{
+    background:url(/static/images/extjs/default/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south{
+    background:url(/static/images/extjs/default/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{
+    background:url(/static/images/extjs/default/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+    background:url(/static/images/extjs/default/sizer/se-handle.gif);
+    background-position: top left;
+}
+.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{
+    background:url(/static/images/extjs/default/sizer/nw-handle.gif);
+    background-position:bottom right;
+}
+.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{
+    background:url(/static/images/extjs/default/sizer/ne-handle.gif);
+    background-position: bottom left;
+}
+.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{
+    background:url(/static/images/extjs/default/sizer/sw-handle.gif);
+    background-position: top right;
+}
+.x-resizable-proxy{
+    border: 1px dashed #6593cf;
+    position:absolute;
+    overflow:hidden;
+    visibility:hidden;
+	 left:0;top:0;
+    z-index:50000;
+}
+.x-resizable-overlay{
+    width:100%;
+	 height:100%;
+	 display:none;
+	 position:absolute;
+	 left:0;
+	 top:0;
+	 background:white;
+	 z-index:200000;
+	 -moz-opacity: 0;
+    opacity:0;
+    filter: alpha(opacity=0);
+}
+
+
+.x-grid {
+	position:relative;
+	overflow:hidden;
+    background:#fff;
+}
+.x-grid-scroller {
+	overflow:auto;
+}
+.x-grid-viewport, .x-grid-locked{
+	position:absolute;
+	left:0; top: 0;
+	z-index:2;
+	overflow:hidden;
+	visibility:hidden;
+}
+.x-grid-cell-inner, .x-grid-hd-inner{
+	overflow:hidden;
+	-o-text-overflow: ellipsis;
+	text-overflow: ellipsis;
+}
+.x-grid-hd-row td, .x-grid-row td{
+	font:normal 11px arial, tahoma, helvetica, sans-serif;
+    line-height:13px;
+    white-space: nowrap;
+	vertical-align: top;
+	-moz-outline: none;
+	-moz-user-focus: normal;
+}
+.x-grid-hd-row td {
+    line-height:14px;
+}
+.x-grid-col {
+	border-right: 1px solid #ebebeb;
+	border-bottom: 1px solid #ebebeb;
+}
+
+
+.x-grid-locked .x-grid-body td {
+	background: #FBFDFF;
+	border-right: 1px solid #deecfd;
+	border-bottom: 1px solid #deecfd !important;
+}
+.x-grid-locked .x-grid-body td .x-grid-cell-inner {
+	border-top:0 none;
+}
+.x-grid-locked .x-grid-row-alt td{
+	background: #F5FAFE;
+}
+
+.x-grid-locked .x-grid-header table{
+    border-right:1px solid transparent;
+}
+.x-grid-locked .x-grid-body table{
+    border-right:1px solid #c3daf9;
+}
+
+.x-grid-locked .x-grid-body td .x-grid-cell-inner {
+	
+}
+.x-grid-row {
+	cursor: default;
+}
+.x-grid-row-alt{
+	background:#f1f1f1;
+}
+.x-grid-row-over td{
+	background:#d9e8fb;
+}
+.x-grid-resize-proxy {
+	width:3px;
+	background:#cccccc;
+	cursor: e-resize;
+	cursor: col-resize;
+	position:absolute;
+	top:0;
+	height:100px;
+	overflow:hidden;
+	visibility:hidden;
+	border:0 none;
+	z-index:7;
+}
+.x-grid-focus {
+	position:absolute;
+	top:0;
+	-moz-outline:0 none;
+    outline:0 none;
+    -moz-user-select: normal;
+    -khtml-user-select: normal;
+}
+
+
+.x-grid-header{
+	background: #ebeadb url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x;
+	overflow:hidden;
+	position:relative;
+	cursor:default;
+	width:100%;
+}
+.x-grid-hd-row{
+	height:22px;
+}
+.x-grid-hd {
+	padding-right:1px;
+}
+.x-grid-hd-over .x-grid-hd-inner {
+	border-bottom: 1px solid #c3daf9;
+}
+.x-grid-hd-over .x-grid-hd-text {
+	background: #fafafa url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x 0 1px;
+	padding-bottom:1px;
+    border-bottom: 1px solid #b3cae9;
+}
+.x-grid-sort-icon{
+	background-repeat: no-repeat;
+	display: none;
+	height: 4px;
+	width: 13px;
+	margin-left:3px;
+	vertical-align: middle;
+}
+.x-grid-header .sort-asc .x-grid-sort-icon {
+	background-image: url(/static/images/extjs/default/grid/sort_asc.gif);
+	display: inline;
+}
+.x-grid-header .sort-desc .x-grid-sort-icon {
+	background-image: url(/static/images/extjs/default/grid/sort_desc.gif);
+	display: inline;
+}
+
+
+.x-grid-body {
+	overflow:hidden;
+	position:relative;
+	width:100%;
+	zoom:1;
+}
+
+.x-grid-cell-text,.x-grid-hd-text {
+	display: block;
+	padding: 3px 5px 3px 5px;
+	-moz-user-select: none;
+	-khtml-user-select: none;
+	color:black;
+}
+.x-grid-hd-text {
+    padding-top:4px;
+}
+.x-grid-split {
+	background-image: url(/static/images/extjs/default/grid/grid-split.gif);
+	background-position: center;
+	background-repeat: no-repeat;
+	cursor: e-resize;
+	cursor: col-resize;
+	display: block;
+	font-size: 1px;
+	height: 16px;
+	overflow: hidden;
+	position: absolute;
+	top: 2px;
+	width: 6px;
+	z-index: 3;
+}
+
+.x-grid-hd-text {
+	color:#15428b;
+}
+
+.x-dd-drag-proxy .x-grid-hd-inner{
+	background: #ebeadb url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x;
+	height:22px;
+	width:120px;
+}
+
+.col-move-top, .col-move-bottom{
+	width:9px;
+	height:9px;
+	position:absolute;
+	top:0;
+	line-height:1px;
+	font-size:1px;
+	overflow:hidden;
+	visibility:hidden;
+	z-index:20000;
+}
+.col-move-top{
+	background:transparent url(/static/images/extjs/default/grid/col-move-top.gif) no-repeat left top;
+}
+.col-move-bottom{
+	background:transparent url(/static/images/extjs/default/grid/col-move-bottom.gif) no-repeat left top;
+}
+
+
+.x-grid-row-selected td, .x-grid-locked .x-grid-row-selected td{
+	background-color: #316ac5 !important;
+	color: white;
+}
+.x-grid-row-selected span, .x-grid-row-selected b, .x-grid-row-selected div, .x-grid-row-selected strong, .x-grid-row-selected i{
+	color: white !important;
+}
+.x-grid-row-selected .x-grid-cell-text{
+	color: white;
+}
+.x-grid-cell-selected{
+	background-color: #316ac5 !important;
+	color: white;
+}
+.x-grid-cell-selected span{
+	color: white !important;
+}
+.x-grid-cell-selected .x-grid-cell-text{
+	color: white;
+}
+
+.x-grid-locked td.x-grid-row-marker, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker{
+    background: #ebeadb url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x 0 bottom !important;
+    vertical-align:middle !important;
+    color:black;
+    padding:0;
+    border-top:1px solid white;
+    border-bottom:none !important;
+    border-right:1px solid #6fa0df !important;
+    text-align:center;
+}
+.x-grid-locked td.x-grid-row-marker div, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker div{
+    padding:0 4px;
+    color:#15428b !important;
+    text-align:center;
+}
+
+
+.x-grid-dirty-cell {
+    background: transparent url(/static/images/extjs/default/grid/dirty.gif) no-repeat 0 0;
+}
+
+
+.x-grid-topbar, .x-grid-bottombar{
+	font:normal 11px arial, tahoma, helvetica, sans-serif;
+    overflow:hidden;
+	display:none;
+	zoom:1;
+    position:relative;
+}
+.x-grid-topbar .x-toolbar{
+	border-right:0 none;
+}
+.x-grid-bottombar .x-toolbar{
+	border-right:0 none;
+	border-bottom:0 none;
+	border-top:1px solid #a9bfd3;
+}
+
+.x-props-grid .x-grid-cell-selected .x-grid-cell-text{
+	 background-color: #316ac5 !important;
+}
+.x-props-grid .x-grid-col-value .x-grid-cell-text{
+	background-color: white;
+}
+.x-props-grid .x-grid-col-name{
+	 background-color: #c3daf9;
+}
+.x-props-grid .x-grid-col-name .x-grid-cell-text{
+	background-color: white;
+    margin-left:10px;
+}
+.x-props-grid .x-grid-split-value {
+    visibility:hidden;
+}
+
+
+.xg-hmenu-sort-asc .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-asc.gif);
+}
+.xg-hmenu-sort-desc .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-desc.gif);
+}
+.xg-hmenu-lock .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-lock.gif);
+}
+.xg-hmenu-unlock .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-unlock.gif);
+}
+
+
+.x-dd-drag-ghost .x-grid-dd-wrap {
+    padding:1px 3px 3px 1px;
+}
+.x-layout-container{
+    width:100%;
+    height:100%;
+    overflow:hidden;
+	 background-color:#c3daf9;
+}
+.x-layout-container .x-layout-tabs-body{
+	border:0 none;
+}
+.x-layout-collapsed{
+    position:absolute;
+    left:-10000px;
+    top:-10000px;
+    visibility:hidden;
+    background-color:#c3daf9;
+    width:20px;
+    height:20px;
+    overflow:hidden;
+	border:1px solid #98c0f4;
+	z-index:20;
+}
+.ext-border-box .x-layout-collapsed{
+    width:22px;
+    height:22px;
+}
+.x-layout-collapsed-over{
+    cursor:pointer;
+	 background-color:#d9e8fb;
+}
+.x-layout-collapsed-west .x-layout-collapsed-tools, .x-layout-collapsed-east .x-layout-collapsed-tools{
+	position:absolute;
+    top:0;
+    left:0;
+    width:20px;
+    height:20px;
+}
+.x-layout-collapsed-north .x-layout-collapsed-tools, .x-layout-collapsed-south .x-layout-collapsed-tools{
+	position:absolute;
+    top:0;
+    right:0;
+    width:20px;
+    height:20px;
+}
+.x-layout-collapsed .x-layout-tools-button{
+    margin:0;
+}
+.x-layout-collapsed .x-layout-tools-button-inner{
+    width:16px;
+    height:16px;
+}
+.x-layout-inactive-content{
+    position:absolute;
+    left:-10000px;
+    top:-10000px;
+    visibility:hidden;
+}
+.x-layout-active-content{
+    visibility:visible;
+}
+.x-layout-panel{
+    position:absolute;border:1px solid #98c0f4;overflow:hidden;background-color:white;
+}
+.x-layout-panel-east, .x-layout-panel-west {
+    z-index:10;
+}
+.x-layout-panel-north, .x-layout-panel-south {
+    z-index:11;
+}
+.x-layout-collapsed-north, .x-layout-collapsed-south, .x-layout-collapsed-east, .x-layout-collapsed-west {
+    z-index:12;
+}
+.x-layout-panel-body{
+    overflow:hidden;
+}
+.x-layout-grid-wrapper{
+
+}
+.x-layout-split{
+    position:absolute;
+    height:5px;
+    width:5px;
+    line-height:1px;
+    font-size:1px;
+    z-index:3;
+    background-color:#c3daf9;
+}
+.x-layout-panel-hd{
+    background-image: url(/static/images/extjs/default/layout/panel-title-light-bg.gif);
+    color: black;
+    border-bottom:1px solid #98c0f4;
+    position:relative;
+}
+.x-layout-panel-hd-text{
+    font:normal 11px tahoma, verdana, helvetica;
+    padding: 4px;
+    padding-left: 4px;
+    display:block;
+	 white-space:nowrap;
+}
+.x-layout-panel-hd-tools{
+    position:absolute;
+    right:0;
+    top:0;
+    text-align:right;
+    padding-top:2px;
+    padding-right:2px;
+    width:60px;
+}
+.x-layout-tools-button{
+    z-index:6;
+    padding:2px;
+    cursor:pointer;
+    float:right;
+}
+.x-layout-tools-button-over{
+    padding:1px;
+    border:1px solid #98c0f4;
+    background-color:white;
+}
+.x-layout-tools-button-inner{
+    height:12px;
+    width:12px;
+    line-height:1px;
+    font-size:1px;
+    background-repeat:no-repeat;
+    background-position:center;
+}
+.x-layout-close{
+    background-image:url(/static/images/extjs/default/layout/panel-close.gif);
+}
+.x-layout-stick{
+    background-image:url(/static/images/extjs/default/layout/stick.gif);
+}
+.x-layout-collapse-west,.x-layout-expand-east{
+    background-image:url(/static/images/extjs/default/layout/collapse.gif);
+}
+.x-layout-expand-west,.x-layout-collapse-east{
+    background-image:url(/static/images/extjs/default/layout/expand.gif);
+}
+.x-layout-collapse-north,.x-layout-expand-south{
+    background-image:url(/static/images/extjs/default/layout/ns-collapse.gif);
+}
+.x-layout-expand-north,.x-layout-collapse-south{
+    background-image:url(/static/images/extjs/default/layout/ns-expand.gif);
+}
+.x-layout-split-h{
+    background-image:url(/static/images/extjs/default/sizer/e-handle.gif);
+    background-position: left;
+}
+.x-layout-split-v{
+    background-image:url(/static/images/extjs/default/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-layout-panel .x-tabs-wrap{
+    background:url(/static/images/extjs/default/layout/gradient-bg.gif);
+}
+.x-layout-panel .x-tabs-body {
+    background-color:white;
+    overflow:auto;height:100%;
+}
+.x-layout-component-panel, .x-layout-nested-layout {
+	position:relative;
+   padding:0;
+	overflow:hidden;
+	width:200px;
+	height:200px;
+}
+.x-layout-nested-layout .x-layout-panel {
+	  border:0 none;
+}
+.x-layout-nested-layout .x-layout-panel-north {
+	  border-bottom:1px solid #98c0f4;
+}
+.x-layout-nested-layout .x-layout-panel-south {
+	  border-top:1px solid #98c0f4;
+}
+.x-layout-nested-layout .x-layout-panel-east {
+	  border-left:1px solid #98c0f4;
+}
+.x-layout-nested-layout .x-layout-panel-west {
+	  border-right:1px solid #98c0f4;
+}
+
+.x-layout-panel-dragover {
+	border: 2px solid #6593cf;
+}
+.x-layout-panel-proxy {
+	background-image: url(/static/images/extjs/default/layout/gradient-bg.gif);
+	background-color:#c3daf9;
+	border:1px dashed #6593cf;
+	z-index:10001;
+	overflow:hidden;
+	position:absolute;
+	left:0;top:0;
+}
+.x-layout-slider {
+	z-index:15;
+	overflow:hidden;
+	position:absolute;
+}
+
+.x-scroller-up, .x-scroller-down {
+	background-color:#c3daf9;
+	border: 1px solid #6593cf;
+	border-top-color: #fff;
+	border-left-color: #fff;
+	border-right:0 none;
+	cursor:pointer;
+	overflow:hidden;
+	line-height:16px;
+}
+.x-scroller-down {
+	border-bottom: 0 none;
+	border-top: 1px solid #6593cf;
+}
+.x-scroller-btn-over {
+	background-color: #d9e8f8;
+}
+.x-scroller-btn-click {
+	background-color: #AECEF7;
+}
+.x-scroller-btn-disabled {
+	cursor:default;
+	background-color: #c3daf9;
+	-moz-opacity: 0.3;
+   opacity:.30;
+   filter: alpha(opacity=30);
+}
+
+
+
+.x-reader .x-layout-panel-north {
+    border:0 none;
+}
+.x-reader .x-layout-panel-center{
+    border:0 none;
+}
+.x-reader .x-layout-nested-layout .x-layout-panel-center{
+    border:1px solid #99bbe8;
+    border-top:0 none;
+}
+.x-reader .x-layout-nested-layout .x-layout-panel-south{
+    border:1px solid #99bbe8;
+}
+.x-dlg-proxy {
+	background-image: url(/static/images/extjs/default/gradient-bg.gif);
+	background-color:#c3daf9;
+	border:1px solid #6593cf;
+	z-index:10001;
+	overflow:hidden;
+	position:absolute;
+	left:0;top:0;
+}
+.x-dlg-shadow{
+	background:#aaaaaa;
+	position:absolute;
+	left:0;top:0;
+}
+.x-dlg-focus{
+	-moz-outline:0 none;
+	outline:0 none;
+	width:0;
+	height:0;
+	overflow:hidden;
+	position:absolute;
+	top:0;
+	left:0;
+}
+.x-dlg-mask{
+	z-index:10000;   
+   display:none;
+   position:absolute;
+   top:0;
+   left:0;
+   -moz-opacity: 0.5;
+   opacity:.50;
+   filter: alpha(opacity=50);
+   background-color:#CCC;
+}
+body.x-body-masked select {
+	visibility:hidden;
+}
+body.x-body-masked .x-dlg select {
+	visibility:visible;
+}
+.x-dlg{
+	z-index:10001;
+	overflow:hidden;
+	position:absolute;
+	left:300;top:0;
+}
+.x-dlg .x-dlg-hd {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) repeat-x 0 -82px;
+	background-color:navy;
+	color:#FFF;
+	font:bold 12px "sans serif", tahoma, verdana, helvetica;
+	overflow:hidden;
+	padding:5px;
+    white-space: nowrap;
+}
+.x-dlg .x-dlg-hd-left {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) no-repeat 0 -41px;
+	padding-left:3px;
+	margin:0;
+}
+.x-dlg .x-dlg-hd-right {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) no-repeat right 0;
+	padding-right:3px;
+}
+.x-dlg .x-dlg-dlg-body{
+	background:url(/static/images/extjs/default/layout/gradient-bg.gif);
+	border:1px solid #6593cf;
+	border-top:0 none;
+	padding:10px;
+	position:absolute;
+	top:24px;left:0;
+	z-index:1;
+	overflow:hidden;
+}
+.x-dlg-collapsed .x-resizable-handle{
+    display:none;
+}
+.x-dlg .x-dlg-bd{
+	overflow:hidden;
+}
+.x-dlg .x-dlg-ft{
+	overflow:hidden;
+	padding:5px;
+	padding-bottom:0;
+}
+.x-dlg .x-tabs-body{
+	background:white;
+	overflow:auto;
+}
+.x-dlg .x-tabs-top .x-tabs-body{
+	border:1px solid #6593cf;
+	border-top:0 none;
+}
+.x-dlg .x-tabs-bottom .x-tabs-body{
+	border:1px solid #6593cf;
+	border-bottom:0 none;
+}
+.x-dlg .x-layout-container  .x-tabs-body{
+	border:0 none;
+}
+.x-dlg .inner-tab{
+	margin:5px;
+}
+.x-dlg .x-dlg-ft .x-btn{
+	margin-right:5px;
+	float:right;
+	clear:none;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns td {
+	border:0;
+	padding:0;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-right table{
+	float:right;
+	clear:none;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-left table{
+	float:left;
+	clear:none;
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-center{
+	text-align:center; 
+}
+.x-dlg .x-dlg-ft .x-dlg-btns-center table{
+	margin:0 auto; 
+}
+.x-dlg-draggable .x-dlg-hd{
+	cursor:move;
+}
+.x-dlg-closable .x-dlg-hd{
+	padding-right:22px;
+}
+.x-dlg-toolbox {
+    position:absolute;
+	top:4px;
+	right:4px;
+	z-index:6;
+    width:40px;
+    cursor:default;
+    height:15px;
+    background:transparent;
+}
+.x-dlg .x-dlg-close, .x-dlg .x-dlg-collapse {
+    float:right;
+    height:15px;
+	width:15px;
+	margin:0;
+    margin-left:2px;
+    padding:0;
+	line-height:1px;
+	font-size:1px;
+	background-repeat:no-repeat;
+	cursor:pointer;
+	visibility:inherit;
+}
+.x-dlg .x-dlg-close {
+    background-image:url(/static/images/extjs/default/basic-dialog/close.gif);
+}
+.x-dlg .x-dlg-collapse {
+    background-image:url(/static/images/extjs/default/basic-dialog/collapse.gif);
+}
+.x-dlg-collapsed .x-dlg-collapse {
+    background-image:url(/static/images/extjs/default/basic-dialog/expand.gif);
+}
+.x-dlg .x-dlg-close-over, .x-dlg .x-dlg-collapse-over {
+    
+}
+.x-dlg div.x-resizable-handle-east{
+	background-image:url(/static/images/extjs/default/basic-dialog/e-handle.gif);
+	border:0;
+	background-position:right;
+	margin-right:0;
+}
+.x-dlg div.x-resizable-handle-south{
+	background-image:url(/static/images/extjs/default/sizer/s-handle-dark.gif);
+	border:0;
+	height:6px;
+}
+.x-dlg div.x-resizable-handle-west{
+	background-image:url(/static/images/extjs/default/basic-dialog/e-handle.gif);
+	border:0;
+	background-position:1px;
+}
+.x-dlg div.x-resizable-handle-north{
+	background-image:url(/static/images/extjs/default/s.gif);
+	border:0;
+}
+.x-dlg div.x-resizable-handle-northeast, .ytheme-gray .x-dlg div.x-resizable-handle-northeast{
+	background-image:url(/static/images/extjs/default/s.gif);
+	border:0;
+}
+.x-dlg div.x-resizable-handle-northwest, .ytheme-gray .x-dlg div.x-resizable-handle-northwest{
+	background-image:url(/static/images/extjs/default/s.gif);
+	border:0;
+}
+.x-dlg div.x-resizable-handle-southeast{
+	background-image:url(/static/images/extjs/default/basic-dialog/se-handle.gif);
+	background-position: bottom right;
+	width:8px;
+	height:8px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-southwest{
+	background-image:url(/static/images/extjs/default/sizer/sw-handle-dark.gif);
+	background-position: top right;
+	margin-left:1px;
+	margin-bottom:1px;
+	border:0;
+}
+
+#x-msg-box .x-dlg-ft .x-btn{
+	float:none;
+	clear:none;
+	margin:0 3px;
+}
+
+#x-msg-box .x-dlg-bd {
+	padding:5px;
+	overflow:hidden !important;
+	font:normal 13px verdana,tahoma,sans-serif;
+}
+#x-msg-box .ext-mb-input {
+	margin-top:4px;
+	width:95%;
+}
+#x-msg-box .ext-mb-textarea {
+	margin-top:4px;
+	font:normal 13px verdana,tahoma,sans-serif;
+}
+#x-msg-box .ext-mb-progress-wrap {
+	margin-top:4px;
+	border:1px solid #6593cf;
+}
+#x-msg-box .ext-mb-progress {
+	height:18px;
+	background: #e0e8f3 url(/static/images/extjs/default/qtip/bg.gif) repeat-x;
+}
+#x-msg-box .ext-mb-progress-bar {
+	height:18px;
+	overflow:hidden;
+	width:0;
+	background:#8BB8F3;
+	border-top:1px solid #B2D0F7;
+	border-bottom:1px solid #65A1EF;
+	border-right:1px solid #65A1EF;
+}
+
+#x-msg-box .x-msg-box-wait {
+	background: transparent url(/static/images/extjs/default/grid/loading.gif) no-repeat left;
+    display:block;
+    width:300px;
+    padding-left:18px;
+    line-height:18px;
+}
+.x-dd-drag-proxy{
+	position:absolute;
+	left:0;top:0;
+	visibility:hidden;
+	z-index:15000;
+}
+.x-dd-drag-ghost{
+	color: black;
+	font: normal 11px arial, helvetica, sans-serif;
+	-moz-opacity: 0.85;
+   opacity:.85;
+   filter: alpha(opacity=85);
+	border-top:1px solid #dddddd;
+	border-left:1px solid #dddddd;
+	border-right:1px solid #bbbbbb;
+	border-bottom:1px solid #bbbbbb;
+	padding:3px;
+	padding-left:20px;
+	background-color:white;
+	white-space:nowrap;
+}
+.x-dd-drag-repair .x-dd-drag-ghost{
+	-moz-opacity: 0.4;
+   opacity:.4;
+   filter: alpha(opacity=40);
+	border:0 none;
+	padding:0;
+	background-color:transparent;
+}
+.x-dd-drag-repair .x-dd-drop-icon{
+	visibility:hidden;
+}
+.x-dd-drop-icon{
+  position:absolute;
+	top:3px;
+	left:3px;
+	display:block;
+	width:16px;
+	height:16px;
+	background-color:transparent;
+	background-position: center;
+	background-repeat: no-repeat;
+	z-index:1;
+}
+.x-dd-drop-nodrop .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/dd/drop-no.gif);
+}
+.x-dd-drop-ok .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/dd/drop-yes.gif);
+}
+.x-dd-drop-ok-add .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/dd/drop-add.gif);
+}
+.x-tree-icon, .x-tree-ec-icon, .x-tree-elbow-line, .x-tree-elbow, .x-tree-elbow-end, .x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{
+	border: 0 none;
+	height: 18px;
+	margin: 0;
+	padding: 0;
+	vertical-align: middle;
+	width: 16px;
+    background-repeat: no-repeat;
+}
+.x-tree-node-collapsed .x-tree-node-icon, .x-tree-node-expanded .x-tree-node-icon, .x-tree-node-leaf .x-tree-node-icon{
+	border: 0 none;
+	height: 18px;
+	margin: 0;
+	padding: 0;
+	vertical-align: middle;
+	width: 16px;
+	background-position:center;
+    background-repeat: no-repeat;
+}
+
+
+.x-tree-node-collapsed .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/folder.gif);
+}
+.x-tree-node-expanded .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/folder-open.gif);
+}
+.x-tree-node-leaf .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/leaf.gif);
+}
+
+.x-tree-noicon .x-tree-node-icon{
+	width:0; height:0;
+}
+
+.x-tree-node-loading .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/loading.gif) !important;
+}
+.x-tree-node-loading a span{
+	 font-style: italic;
+	 color:#444444;
+}
+
+
+.x-tree-lines .x-tree-elbow{
+	background-image:url(/static/images/extjs/default/tree/elbow.gif);
+}
+.x-tree-lines .x-tree-elbow-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-plus.gif);
+}
+.x-tree-lines .x-tree-elbow-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-minus.gif);
+}
+.x-tree-lines .x-tree-elbow-end{
+	background-image:url(/static/images/extjs/default/tree/elbow-end.gif);
+}
+.x-tree-lines .x-tree-elbow-end-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-plus.gif);
+}
+.x-tree-lines .x-tree-elbow-end-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-minus.gif);
+}
+.x-tree-lines .x-tree-elbow-line{
+	background-image:url(/static/images/extjs/default/tree/elbow-line.gif);
+}
+
+
+.x-tree-no-lines .x-tree-elbow{
+	background:transparent;
+}
+.x-tree-no-lines .x-tree-elbow-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-plus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-minus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-end{
+	background:transparent;
+}
+.x-tree-no-lines .x-tree-elbow-end-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-plus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-end-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-minus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-line{
+	background:transparent;
+}
+
+.x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{
+	cursor:pointer;
+}
+.ext-ie ul.x-tree-node-ct{
+    font-size:0;
+    line-height:0;
+}
+.x-tree-node{
+	color: black;
+	font: normal 11px arial, tahoma, helvetica, sans-serif;
+	white-space: nowrap;
+}
+.x-tree-node a, .x-dd-drag-ghost a{
+	text-decoration:none;
+	color:black;
+	-khtml-user-select:none;
+	-moz-user-select:none;
+    -kthml-user-focus:normal;
+    -moz-user-focus:normal;
+    -moz-outline: 0 none;
+    outline:0 none;
+}
+.x-tree-node a span, .x-dd-drag-ghost a span{
+	text-decoration:none;
+	color:black;
+	padding:1px 3px 1px 2px;
+}
+.x-tree-node .x-tree-node-disabled a span{
+	color:gray !important;
+}
+.x-tree-node .x-tree-node-disabled .x-tree-node-icon{
+	-moz-opacity: 0.5;
+   opacity:.5;
+   filter: alpha(opacity=50);
+}
+.x-tree-node .x-tree-node-inline-icon{
+	background:transparent;
+}
+.x-tree-node a:hover, .x-dd-drag-ghost a:hover{
+	text-decoration:none;
+}
+.x-tree-node div.x-tree-drag-insert-below{
+ 	 border-bottom:1px dotted #3366cc;
+}
+.x-tree-node div.x-tree-drag-insert-above{
+	 border-top:1px dotted #3366cc;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below{
+ 	 border-bottom:0 none;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above{
+	 border-top:0 none;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{
+ 	 border-bottom:2px solid #3366cc;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{
+	 border-top:2px solid #3366cc;
+}
+.x-tree-node .x-tree-drag-append a span{
+	 background:#dddddd;
+	 border:1px dotted gray;
+}
+.x-tree-node .x-tree-selected a span{
+	background:#3366cc;
+	color:white;
+}
+.x-dd-drag-ghost .x-tree-node-indent, .x-dd-drag-ghost .x-tree-ec-icon{
+	display:none !important;
+}
+.x-tree-drop-ok-append .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-add.gif);
+}
+.x-tree-drop-ok-above .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-over.gif);
+}
+.x-tree-drop-ok-below .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-under.gif);
+}
+.x-tree-drop-ok-between .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-between.gif);
+}
+
+.x-tip{
+	position: absolute;
+	top: 0;
+    left:0;
+    visibility: hidden;
+	z-index: 20000;
+    border:0 none;
+}
+.x-tip .x-tip-close{
+	background-image: url(/static/images/extjs/default/qtip/close.gif);
+	height: 15px;
+	float:right;
+	width: 15px;
+    margin:0 0 2px 2px;
+    cursor:pointer;
+    display:none;
+}
+.x-tip .x-tip-top {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -12px;
+	height:6px;
+    overflow:hidden;
+}
+.x-tip .x-tip-top-left {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 0;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-top-right {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat right 0;
+	padding-right:6px;
+    zoom:1;
+}
+.x-tip .x-tip-ft {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -18px;
+	height:6px;
+    overflow:hidden;
+}
+.x-tip .x-tip-ft-left {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -6px;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-ft-right {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat right -6px;
+	padding-right:6px;
+    zoom:1;
+}
+.x-tip .x-tip-bd {
+    border:0 none;
+    font: normal 11px tahoma,arial,helvetica,sans-serif;
+}
+.x-tip .x-tip-bd-left {
+	background: #fff url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -24px;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-bd-right {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat right -24px;
+	padding-right:6px;
+    zoom:1;
+}
+
+.x-tip h3 {
+    font: bold 12px tahoma,arial,helvetica,sans-serif;
+    margin:0;
+    padding:2px 2px;
+    color:#222;
+}
+.x-tip .x-tip-bd-inner {
+    margin:0 !important;
+    line-height:14px;
+    color:#222;
+    padding:0;
+    float:left;
+}
+
+
+.x-form-invalid-tip {
+}
+
+.x-form-invalid-tip .x-tip-top {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-top-left {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-top-right {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-ft {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-ft-left {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-ft-right {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-bd-left {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-bd-right {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-bd .x-tip-bd-inner {
+    padding-left:24px;
+    background:transparent url(/static/images/extjs/default/form/exclamation.gif) no-repeat 2px 2px;
+}
+.x-form-invalid-tip .x-tip-bd-inner {
+    padding:2px;
+}
+.x-date-picker {
+    border: 1px solid #1b376c;
+    border-top:0 none;
+    background:#fff;
+}
+.x-date-picker a {
+    -moz-outline:0 none;
+    outline:0 none;
+}
+.x-date-inner, .x-date-inner td, .x-date-inner th{
+    border-collapse:separate;
+}
+.x-date-middle,.x-date-left,.x-date-right {
+	background: url(/static/images/extjs/default/basic-dialog/hd-sprite.gif) repeat-x 0 -83px;
+	color:#FFF;
+	font:bold 11px "sans serif", tahoma, verdana, helvetica;
+	overflow:hidden;
+}
+
+.x-date-middle .x-btn-left,.x-date-middle .x-btn-center,.x-date-middle .x-btn-right{
+	background:transparent !important;
+    vertical-align:middle;
+}
+.x-date-middle .x-btn .x-btn-text {
+    color:#fff;
+}
+.x-date-middle .x-btn-with-menu  .x-btn-center em {
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow-light.gif) no-repeat right 0;
+}
+.x-date-right, .x-date-left {
+    width:18px;
+}
+.x-date-right{
+    text-align:right;
+}
+.x-date-middle {
+    padding-top:2px;padding-bottom:2px;
+}
+.x-date-right a, .x-date-left a{
+    display:block;
+    width:16px;
+	height:16px;
+	background-position: center;
+	background-repeat: no-repeat;
+	cursor:pointer;
+    -moz-opacity: 0.6;
+    opacity:.6;
+    filter: alpha(opacity=60);
+}
+.x-date-right a:hover, .x-date-left a:hover{
+    -moz-opacity: 1;
+    opacity:1;
+    filter: alpha(opacity=100);
+}
+.x-date-right a {
+    background-image: url(/static/images/extjs/default/shared/right-btn.gif);
+    margin-right:2px;
+}
+.x-date-left a{
+	background-image: url(/static/images/extjs/default/shared/left-btn.gif);
+    margin-left:2px;
+}
+table.x-date-inner {
+    width:100%;
+    table-layout:fixed;
+}
+.x-date-inner th {
+    width:25px;
+}
+.x-date-inner th {
+    background: #c3daf9;
+    text-align:right !important;
+	border-bottom: 1px solid #a3bad9;
+    font:normal 10px arial, helvetica,tahoma,sans-serif;
+	color:#233d6d;
+	cursor:default;
+    padding:0;
+    border-collapse:separate;
+}
+.x-date-inner th span {
+    display:block;
+    padding:2px;
+    padding-right:7px;
+}
+.x-date-inner td {
+    border: 1px solid #fff;
+	text-align:right;
+    padding:0;
+}
+.x-date-inner a {
+    padding:2px 5px;
+    display:block;
+    font:normal 11px arial, helvetica,tahoma,sans-serif;
+	text-decoration:none;
+    color:black;
+    text-align:right;
+    zoom:1;
+}
+.x-date-inner .x-date-active{
+	cursor:pointer;
+	color:black;
+}
+.x-date-inner .x-date-selected a{
+	background: #ddecfe;
+	border: 1px solid #a3bad9;
+    padding:1px 4px;
+}
+.x-date-inner .x-date-today a{
+	border: 1px solid darkred;
+    padding:1px 4px;
+}
+.x-date-inner .x-date-selected span{
+    font-weight:bold;
+}
+.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a {
+	color:#aaaaaa;
+}
+.x-date-bottom {
+    padding:4px;
+    border-top: 1px solid #a3bad9;
+    background: #c3daf9;
+}
+
+.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{
+    text-decoration:none;
+    color:black;
+    background: #ddecfe;
+}
+
+.x-date-inner .x-date-disabled a {
+	cursor:default;
+	background:#eeeeee;
+	color:#bbbbbb;
+}
+.x-date-mmenu{
+    background:#eeeeee !important;
+}
+.x-date-mmenu .x-menu-item {
+	font-size:10px;
+	padding:1px 24px 1px 4px;
+	white-space: nowrap;
+	color:#000;
+}
+.x-date-mmenu .x-menu-item .x-menu-item-icon {
+    width:10px;height:10px;margin-right:5px;
+    background-position:center -4px !important;
+}
+.x-menu {
+	border:1px solid;
+    border-color: #a3bad9 #8BB8F3 #8BB8F3 #a3bad9;
+    z-index: 15000;
+	background: #fff url(/static/images/extjs/default/menu/menu.gif) repeat-y;
+}
+.ext-ie .x-menu {
+    zoom:1;
+    overflow:hidden;
+}
+.x-menu-list{
+    border:1px solid #fff;
+}
+.x-menu li{
+	line-height:100%;
+}
+.x-menu li.x-menu-sep-li{
+	line-height:1px;
+}
+.x-menu-list-item{
+	font:normal 11px "Segoe UI",tahoma,"Lucida Sans Unicode",arial, sans-serif;
+    white-space: nowrap;
+    -moz-user-select: none;
+	-khtml-user-select: none;
+	display:block;
+	padding:1px;
+}
+.x-menu-item-arrow{
+	background:transparent url(/static/images/extjs/default/menu/menu-parent.gif) no-repeat right;
+}
+.x-menu-sep {
+	display:block;
+	font-size:1px;
+	background:#c3daf9;
+	margin: 3px 3px 3px 32px;
+    height:1px;
+}
+.x-menu-focus {
+	position:absolute;
+	left:0;
+	top:-5px;
+	width:0;
+	height:0;
+    line-height:1px;
+}
+.x-menu-item {
+	display:block;
+	line-height:14px;
+	padding:3px 21px 3px 3px;
+	white-space: nowrap;
+	text-decoration:none;
+	color:#233d6d;
+	-moz-outline: 0 none;
+	outline: 0 none;
+	cursor:pointer;
+}
+.x-menu-item-active {
+	color:#233d6d;
+	background:#c3daf9;
+	border:1px solid #8BB8F3;
+	padding:0;
+}
+.x-menu-item-icon {
+	border: 0 none;
+	height: 16px;
+	padding: 0;
+	vertical-align: middle;
+	width: 16px;
+	margin: 0 11px 0 0;
+    background-position:center;
+}
+
+.x-menu-check-item .x-menu-item-icon{
+	background: transparent url(/static/images/extjs/default/menu/unchecked.gif) no-repeat center;
+}
+
+.x-menu-item-checked .x-menu-item-icon{
+	background-image:url(/static/images/extjs/default/menu/checked.gif);
+}
+.x-menu-group-item .x-menu-item-icon{
+	background: transparent;
+}
+
+.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{
+    background: transparent url(/static/images/extjs/default/menu/group-checked.gif) no-repeat center;
+}
+
+.x-menu-plain {
+	background:#fff;
+}
+.x-menu-date-item{
+	padding:0;
+}
+
+.x-menu .x-color-palette, .x-menu .x-date-picker{
+    margin-left:32px;
+	margin-right:4px;
+}
+.x-menu .x-date-picker{
+    border:1px solid #a3bad9;
+    margin-top:2px;
+    margin-bottom:2px;
+}
+.x-menu-plain .x-color-palette, .x-menu-plain .x-date-picker{
+	margin:0;
+    border:0 none;
+}
+
+
+
+.x-box-tl {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat 0 0;
+    zoom:1;
+}
+
+.x-box-tc {
+	height: 8px;
+	background: transparent url(/static/images/extjs/default/box/tb.gif) repeat-x 0 0;
+	overflow: hidden;
+}
+
+.x-box-tr {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat right -8px;
+}
+
+.x-box-ml {
+	background: transparent url(/static/images/extjs/default/box/l.gif) repeat-y 0;
+	padding-left: 4px;
+	overflow: hidden;
+    zoom:1;
+}
+
+.x-box-mc {
+	background: #eee url(/static/images/extjs/default/box/tb.gif) repeat-x 0 -16px;
+	padding: 4px 10px;
+	font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif;
+	color: #393939;
+	font-size: 12px;
+}
+
+.x-box-mc h3 {
+	font-size: 14px;
+	font-weight: bold;
+	margin: 0 0 4 0;
+    zoom:1;
+}
+
+.x-box-mr {
+	background: transparent url(/static/images/extjs/default/box/r.gif) repeat-y right;
+	padding-right: 4px;
+	overflow: hidden;
+}
+
+.x-box-bl {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat 0 -16px;
+    zoom:1;
+}
+
+.x-box-bc {
+	background: transparent url(/static/images/extjs/default/box/tb.gif) repeat-x 0 -8px;
+	height: 8px;
+	overflow: hidden;
+}
+
+.x-box-br {
+	background: transparent url(/static/images/extjs/default/box/corners.gif) no-repeat right -24px;
+}
+
+.x-box-tl, .x-box-bl {
+	padding-left: 8px;
+	overflow: hidden;
+}
+
+.x-box-tr, .x-box-br {
+	padding-right: 8px;
+	overflow: hidden;
+}
+
+.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr {
+	background-image: url(/static/images/extjs/default/box/corners-blue.gif);
+}
+
+.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc {
+	background-image: url(/static/images/extjs/default/box/tb-blue.gif);
+}
+
+.x-box-blue .x-box-mc {
+	background-color: #c3daf9;
+}
+
+.x-box-blue .x-box-mc h3 {
+	color: #17385b;
+}
+
+.x-box-blue .x-box-ml {
+	background-image: url(/static/images/extjs/default/box/l-blue.gif);
+}
+
+.x-box-blue .x-box-mr {
+	background-image: url(/static/images/extjs/default/box/r-blue.gif);
+}
+#x-debug-browser .x-tree .x-tree-node a span {
+    color:#222297;
+    font-size:12px;
+    padding-top:2px;
+    font-family:"courier","courier new";
+    line-height:18px;
+}
+#x-debug-browser .x-tree a i {
+    color:#FF4545;
+    font-style:normal;
+}
+#x-debug-browser .x-tree a em {
+    color:#999;
+}
+#x-debug-browser .x-tree .x-tree-node .x-tree-selected a span{
+    background:#c3daf9;
+}
+#x-debug-browser pre, .x-debug-browser pre xmp {
+    font:normal 11px tahoma, arial, helvetica, sans-serif !important;
+    white-space: -moz-pre-wrap;
+    white-space: -pre-wrap;
+    white-space: -o-pre-wrap;
+    word-wrap: break-word;
+}
+#x-debug-browser pre {
+    display:block;
+    padding:5px !important;
+    border-bottom:1px solid #eeeeee !important;
+}
+#x-debug-browser pre xmp {
+    padding:0 !important;
+    margin:0 !important;
+}
+#x-debug-console .x-layout-panel-center, #x-debug-inspector .x-layout-panel-center {
+      border-right:1px solid #98c0f4;
+}
+#x-debug-console textarea {
+    border: 0 none;
+    font-size:12px;
+    font-family:"courier","courier new";
+    padding-top:4px;
+    padding-left:4px;
+}
+.x-debug-frame {
+    background:#eeeeee;
+    border:1px dashed #aaaaaa;
+}
+.x-combo-list {
+    border:1px solid #98c0f4;
+    background:#ddecfe;
+    zoom:1;
+    overflow:hidden;
+}
+.x-combo-list-inner {
+    overflow:auto;
+    background:white;
+    position:relative; 
+}
+.x-combo-list-hd {
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+    color:#15428b;
+    background-image: url(/static/images/extjs/default/layout/panel-title-light-bg.gif);
+    border-bottom:1px solid #98c0f4;
+    padding:3px;
+}
+.x-resizable-pinned .x-combo-list-inner {
+    border-bottom:1px solid #98c0f4;
+}
+.x-combo-list-item {
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+    padding:2px;
+    border:1px solid #fff;
+    zoom:1;
+    white-space: nowrap;
+    overflow:hidden;
+    text-overflow: ellipsis;
+}
+.x-combo-list .x-combo-selected{
+	background-color: #c3daf9 !important;
+    cursor:pointer;
+    border:1px solid #336699;
+}
+.x-combo-noedit{
+    cursor:pointer;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/form.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/form.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,337 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+/* all fields */
+.x-form-field{
+    margin: 0 0 0 0;
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+/* ---- text fields ---- */
+.x-form-text, textarea.x-form-field{
+    padding: 1px 3px;
+    background:#fff url(/static/images/extjs/default/form/text-bg.gif) repeat-x 0 0;
+    border: 1px solid #B5B8C8;
+}
+.x-form-text {
+    height:22px;
+    line-height:18px;
+    vertical-align:middle;
+}
+.ext-ie .x-form-text {
+    margin-top:-1px; /* ie bogus margin bug */
+    margin-bottom:-1px;
+    height:22px; /* ie quirks */
+    line-height:18px;
+}
+.ext-strict .x-form-text {
+    height:18px;
+}
+.ext-safari .x-form-text {
+    height:20px; /* safari always same size */
+}
+.ext-gecko .x-form-text {
+    padding-top:2px; /* FF won't center the text vertically */
+    padding-bottom:0;
+}
+/* select boxes */
+
+.x-form-select-one {
+    height:20px;
+    line-height:18px;
+    vertical-align:middle;
+    background-color:#fff; /* opera */
+    border: 1px solid #B5B8C8;
+}
+
+/* multi select boxes */
+
+/* --- TODO --- */
+
+/* checkboxes */
+
+/* --- TODO --- */
+
+/* radios */
+
+/* --- TODO --- */
+
+
+/* wrapped fields and triggers */
+
+.x-form-field-wrap {
+    position:relative;
+    zoom:1;
+    white-space: nowrap;
+}
+
+.x-editor .x-form-check-wrap {
+    background:#fff;
+}
+.x-form-field-wrap .x-form-trigger{
+    width:17px;
+    height:21px;
+    border:0;
+    background:transparent url(/static/images/extjs/default/form/trigger.gif) no-repeat 0 0;
+    cursor:pointer;
+    border-bottom: 1px solid #B5B8C8;
+    position:absolute;
+    top:0;
+}
+.ext-safari .x-form-field-wrap .x-form-trigger{
+    height:19px; /* safari doesn't allow height adjustments to the fields, so adjust trigger */
+}
+.x-form-field-wrap .x-form-trigger-over{
+    background-position:-17px 0;
+}
+.x-form-field-wrap .x-form-trigger-click{
+    background-position:-34px 0;
+}
+.x-item-disabled .x-form-trigger-over{
+    background-position:0 0 !important;
+}
+.x-item-disabled .x-form-trigger-click{
+    background-position:0 0 !important;
+}
+.x-form-field-wrap .x-form-date-trigger{
+    background:transparent url(/static/images/extjs/default/form/date-trigger.gif) no-repeat 0 0;
+    cursor:pointer;
+}
+.ext-safari .x-form-field-wrap .x-form-date-trigger{
+    right:0;
+}
+
+/* field focus style */
+.x-form-focus{
+	border: 1px solid #7eadd9;
+}
+
+/* invalid fields */
+.x-form-invalid{
+	background:#fff url(/static/images/extjs/default/grid/invalid_line.gif) repeat-x bottom;
+	border: 1px solid #dd7870;
+}
+.ext-safari .x-form-invalid{
+	background-color:#ffeeee;
+	border: 1px solid #ff7870;
+}
+
+/* editors */
+
+.x-editor {
+    visibility:hidden;
+    padding:0;
+    margin:0;
+}
+.x-form-check-wrap {
+    line-height:18px;
+}
+.ext-ie .x-form-check-wrap input {
+    width:15px;
+    height:15px;
+}
+.x-editor .x-form-check-wrap {
+    padding:3px;
+}
+.x-editor .x-form-checkbox {
+    height:13px;
+    border: 0 none;
+}
+/* If you override the default field font above, you would need to change this font as well */
+.x-form-grow-sizer {
+	font:normal 12px tahoma, arial, helvetica, sans-serif;
+    left: -10000px;
+	padding: 8px 3px;
+    position: absolute;
+    visibility:hidden;
+    top: -10000px;
+	white-space: pre-wrap;
+    white-space: -moz-pre-wrap;
+    white-space: -pre-wrap;
+    white-space: -o-pre-wrap;
+    word-wrap: break-word;
+    zoom:1;
+}
+
+/* This CSS is not final and is subject to change - jvs 03/07/07 */
+
+.x-form-item {
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+    display:block;
+    margin-bottom:4px;
+}
+
+.x-form-item label {
+    display:block;
+    float:left;
+    width:100px;
+    padding:3px;
+    padding-left:0;
+    clear:left;
+}
+
+.x-form-element {
+    padding-left:105px;
+    position:relative;
+}
+
+.x-form-invalid-msg {
+    color:#ee0000;
+    padding:2px;
+    padding-left:18px;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+    background: transparent url(/static/images/extjs/default/shared/warning.gif) no-repeat 0 2px;
+    line-height:16px;
+    width:200px;
+}
+
+.x-form-label-right label {
+   text-align:right;
+}
+
+.x-form-label-top .x-form-item label {
+    width:auto;
+    float:none;
+    clear:none;
+    display:inline;
+    margin-bottom:4px;
+}
+.x-form-label-top .x-form-element {
+    padding-left:0;
+    padding-top:4px;
+}
+.x-form-label-top .x-form-item {
+    padding-bottom:4px;
+}
+.x-form fieldset {
+    border:1px solid #B5B8C8;
+    padding:10px 10px 5px 10px;
+    margin-bottom:10px;
+}
+.x-form fieldset legend {
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+    color:#15428b;
+}
+.ext-ie .x-form fieldset legend {
+    margin-bottom:10px;
+}
+.x-form-empty-field {
+    color:gray;
+}
+/* Editor small font for grid, toolbar and tree */
+.x-small-editor .x-form-field {
+    font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.x-small-editor .x-form-text {
+    height:20px;
+    line-height:16px;
+    vertical-align:middle;
+}
+.ext-ie .x-small-editor .x-form-text {
+    margin-top:-1px !important; /* ie bogus margin bug */
+    margin-bottom:-1px !important;
+    height:20px !important; /* ie quirks */
+    line-height:16px !important;
+}
+.ext-strict .x-small-editor .x-form-text {
+    height:16px !important;
+}
+.ext-safari .x-small-editor .x-form-field {
+    /* safari text field will not size so needs bigger font */
+    font:normal 12px arial, tahoma, helvetica, sans-serif;
+}
+.ext-ie .x-small-editor .x-form-text {
+    height:20px;
+    line-height:16px;
+}
+.ext-border-box .x-small-editor .x-form-text {
+    height:20px;
+}
+
+.x-small-editor .x-form-select-one {
+    height:20px;
+    line-height:16px;
+    vertical-align:middle;
+}
+.x-small-editor .x-form-num-field {
+    text-align:right;
+}
+.x-small-editor .x-form-field-wrap .x-form-trigger{
+    height:19px;
+}
+
+
+.x-form-clear {
+    clear:both;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+.x-form-clear-left {
+    clear:left;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+
+.x-form-cb-label {
+    width:'auto' !important;
+    float:none !important;
+    clear:none !important;
+    display:inline !important;
+    margin-left:4px;
+}
+
+.x-form-column {
+    float:left;
+    padding:0;
+    margin:0;
+    width:48%;
+    overflow:hidden;
+    zoom:1;
+}
+
+/* buttons */
+.x-form .x-form-btns-ct .x-btn{
+	float:right;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns td {
+	border:0;
+	padding:0;
+}
+.x-form .x-form-btns-ct .x-form-btns-right table{
+	float:right;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns-left table{
+	float:left;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns-center{
+	text-align:center; /*ie*/
+}
+.x-form .x-form-btns-ct .x-form-btns-center table{
+	margin:0 auto; /*everyone else*/
+}
+.x-form .x-form-btns-ct table td.x-form-btn-td{
+	padding:3px;
+}
+
+.x-form-invalid-icon {
+    width:16px;
+    height:18px;
+    visibility:hidden;
+    position:absolute;
+    left:0;
+    top:0;
+    display:block;
+    background:transparent url(/static/images/extjs/default/form/exclamation.gif) no-repeat 0 2px;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/grid.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/grid.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,295 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+/* Grid2 styles */
+.x-grid {
+	position:relative;
+	overflow:hidden;
+    background:#fff;
+}
+.x-grid-scroller {
+	overflow:auto;
+}
+.x-grid-viewport, .x-grid-locked{
+	position:absolute;
+	left:0; top: 0;
+	z-index:2;
+	overflow:hidden;
+	visibility:hidden;
+}
+.x-grid-cell-inner, .x-grid-hd-inner{
+	overflow:hidden;
+	-o-text-overflow: ellipsis;
+	text-overflow: ellipsis;
+}
+.x-grid-hd-row td, .x-grid-row td{
+	font:normal 11px arial, tahoma, helvetica, sans-serif;
+    line-height:13px;
+    white-space: nowrap;
+	vertical-align: top;
+	-moz-outline: none;
+	-moz-user-focus: normal;
+}
+.x-grid-hd-row td {
+    line-height:14px;
+}
+.x-grid-col {
+	border-right: 1px solid #ebebeb;
+	border-bottom: 1px solid #ebebeb;
+}
+/* Locked styles */
+
+.x-grid-locked .x-grid-body td {
+	background: #FBFDFF;
+	border-right: 1px solid #deecfd;
+	border-bottom: 1px solid #deecfd !important;
+}
+.x-grid-locked .x-grid-body td .x-grid-cell-inner {
+	border-top:0 none;
+}
+.x-grid-locked .x-grid-row-alt td{
+	background: #F5FAFE;
+}
+
+.x-grid-locked .x-grid-header table{
+    border-right:1px solid transparent;
+}
+.x-grid-locked .x-grid-body table{
+    border-right:1px solid #c3daf9;
+}
+
+.x-grid-locked .x-grid-body td .x-grid-cell-inner {
+	
+}
+.x-grid-row {
+	cursor: default;
+}
+.x-grid-row-alt{
+	background:#f1f1f1;
+}
+.x-grid-row-over td{
+	background:#d9e8fb;
+}
+.x-grid-resize-proxy {
+	width:3px;
+	background:#cccccc;
+	cursor: e-resize;
+	cursor: col-resize;
+	position:absolute;
+	top:0;
+	height:100px;
+	overflow:hidden;
+	visibility:hidden;
+	border:0 none;
+	z-index:7;
+}
+.x-grid-focus {
+	position:absolute;
+	top:0;
+	-moz-outline:0 none;
+    outline:0 none;
+    -moz-user-select: normal;
+    -khtml-user-select: normal;
+}
+
+/* header styles */
+.x-grid-header{
+	background: #ebeadb url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x;
+	overflow:hidden;
+	position:relative;
+	cursor:default;
+	width:100%;
+}
+.x-grid-hd-row{
+	height:22px;
+}
+.x-grid-hd {
+	padding-right:1px;
+}
+.x-grid-hd-over .x-grid-hd-inner {
+	border-bottom: 1px solid #c3daf9;
+}
+.x-grid-hd-over .x-grid-hd-text {
+	background: #fafafa url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x 0 1px;
+	padding-bottom:1px;
+    border-bottom: 1px solid #b3cae9;
+}
+.x-grid-sort-icon{
+	background-repeat: no-repeat;
+	display: none;
+	height: 4px;
+	width: 13px;
+	margin-left:3px;
+	vertical-align: middle;
+}
+.x-grid-header .sort-asc .x-grid-sort-icon {
+	background-image: url(/static/images/extjs/default/grid/sort_asc.gif);
+	display: inline;
+}
+.x-grid-header .sort-desc .x-grid-sort-icon {
+	background-image: url(/static/images/extjs/default/grid/sort_desc.gif);
+	display: inline;
+}
+
+/* Body Styles */
+.x-grid-body {
+	overflow:hidden;
+	position:relative;
+	width:100%;
+	zoom:1;
+}
+
+.x-grid-cell-text,.x-grid-hd-text {
+	display: block;
+	padding: 3px 5px 3px 5px;
+	-moz-user-select: none;
+	-khtml-user-select: none;
+	color:black;
+}
+.x-grid-hd-text {
+    padding-top:4px;
+}
+.x-grid-split {
+	background-image: url(/static/images/extjs/default/grid/grid-split.gif);
+	background-position: center;
+	background-repeat: no-repeat;
+	cursor: e-resize;
+	cursor: col-resize;
+	display: block;
+	font-size: 1px;
+	height: 16px;
+	overflow: hidden;
+	position: absolute;
+	top: 2px;
+	width: 6px;
+	z-index: 3;
+}
+
+.x-grid-hd-text {
+	color:#15428b;
+}
+/* Column Reorder DD */
+.x-dd-drag-proxy .x-grid-hd-inner{
+	background: #ebeadb url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x;
+	height:22px;
+	width:120px;
+}
+
+.col-move-top, .col-move-bottom{
+	width:9px;
+	height:9px;
+	position:absolute;
+	top:0;
+	line-height:1px;
+	font-size:1px;
+	overflow:hidden;
+	visibility:hidden;
+	z-index:20000;
+}
+.col-move-top{
+	background:transparent url(/static/images/extjs/default/grid/col-move-top.gif) no-repeat left top;
+}
+.col-move-bottom{
+	background:transparent url(/static/images/extjs/default/grid/col-move-bottom.gif) no-repeat left top;
+}
+
+/* Selection Styles */
+.x-grid-row-selected td, .x-grid-locked .x-grid-row-selected td{
+	background-color: #316ac5 !important;
+	color: white;
+}
+.x-grid-row-selected span, .x-grid-row-selected b, .x-grid-row-selected div, .x-grid-row-selected strong, .x-grid-row-selected i{
+	color: white !important;
+}
+.x-grid-row-selected .x-grid-cell-text{
+	color: white;
+}
+.x-grid-cell-selected{
+	background-color: #316ac5 !important;
+	color: white;
+}
+.x-grid-cell-selected span{
+	color: white !important;
+}
+.x-grid-cell-selected .x-grid-cell-text{
+	color: white;
+}
+
+.x-grid-locked td.x-grid-row-marker, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker{
+    background: #ebeadb url(/static/images/extjs/default/grid/grid-hrow.gif) repeat-x 0 bottom !important;
+    vertical-align:middle !important;
+    color:black;
+    padding:0;
+    border-top:1px solid white;
+    border-bottom:none !important;
+    border-right:1px solid #6fa0df !important;
+    text-align:center;
+}
+.x-grid-locked td.x-grid-row-marker div, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker div{
+    padding:0 4px;
+    color:#15428b !important;
+    text-align:center;
+}
+
+/* dirty cells */
+.x-grid-dirty-cell {
+    background: transparent url(/static/images/extjs/default/grid/dirty.gif) no-repeat 0 0;
+}
+
+/* Grid Toolbars */
+.x-grid-topbar, .x-grid-bottombar{
+	font:normal 11px arial, tahoma, helvetica, sans-serif;
+    overflow:hidden;
+	display:none;
+	zoom:1;
+    position:relative;
+}
+.x-grid-topbar .x-toolbar{
+	border-right:0 none;
+}
+.x-grid-bottombar .x-toolbar{
+	border-right:0 none;
+	border-bottom:0 none;
+	border-top:1px solid #a9bfd3;
+}
+/* Props Grid Styles */
+.x-props-grid .x-grid-cell-selected .x-grid-cell-text{
+	 background-color: #316ac5 !important;
+}
+.x-props-grid .x-grid-col-value .x-grid-cell-text{
+	background-color: white;
+}
+.x-props-grid .x-grid-col-name{
+	 background-color: #c3daf9;
+}
+.x-props-grid .x-grid-col-name .x-grid-cell-text{
+	background-color: white;
+    margin-left:10px;
+}
+.x-props-grid .x-grid-split-value {
+    visibility:hidden;
+}
+
+/* header menu */
+.xg-hmenu-sort-asc .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-asc.gif);
+}
+.xg-hmenu-sort-desc .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-desc.gif);
+}
+.xg-hmenu-lock .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-lock.gif);
+}
+.xg-hmenu-unlock .x-menu-item-icon{
+	background-image: url(/static/images/extjs/default/grid/hmenu-unlock.gif);
+}
+
+/* dd */
+.x-dd-drag-ghost .x-grid-dd-wrap {
+    padding:1px 3px 3px 1px;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/layout.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/layout.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,252 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-layout-container{
+    width:100%;
+    height:100%;
+    overflow:hidden;
+	 background-color:#c3daf9;
+}
+.x-layout-container .x-layout-tabs-body{
+	border:0 none;
+}
+.x-layout-collapsed{
+    position:absolute;
+    left:-10000px;
+    top:-10000px;
+    visibility:hidden;
+    background-color:#c3daf9;
+    width:20px;
+    height:20px;
+    overflow:hidden;
+	border:1px solid #98c0f4;
+	z-index:20;
+}
+.ext-border-box .x-layout-collapsed{
+    width:22px;
+    height:22px;
+}
+.x-layout-collapsed-over{
+    cursor:pointer;
+	 background-color:#d9e8fb;
+}
+.x-layout-collapsed-west .x-layout-collapsed-tools, .x-layout-collapsed-east .x-layout-collapsed-tools{
+	position:absolute;
+    top:0;
+    left:0;
+    width:20px;
+    height:20px;
+}
+.x-layout-collapsed-north .x-layout-collapsed-tools, .x-layout-collapsed-south .x-layout-collapsed-tools{
+	position:absolute;
+    top:0;
+    right:0;
+    width:20px;
+    height:20px;
+}
+.x-layout-collapsed .x-layout-tools-button{
+    margin:0;
+}
+.x-layout-collapsed .x-layout-tools-button-inner{
+    width:16px;
+    height:16px;
+}
+.x-layout-inactive-content{
+    position:absolute;
+    left:-10000px;
+    top:-10000px;
+    visibility:hidden;
+}
+.x-layout-active-content{
+    visibility:visible;
+}
+.x-layout-panel{
+    position:absolute;border:1px solid #98c0f4;overflow:hidden;background-color:white;
+}
+.x-layout-panel-east, .x-layout-panel-west {
+    z-index:10;
+}
+.x-layout-panel-north, .x-layout-panel-south {
+    z-index:11;
+}
+.x-layout-collapsed-north, .x-layout-collapsed-south, .x-layout-collapsed-east, .x-layout-collapsed-west {
+    z-index:12;
+}
+.x-layout-panel-body{
+    overflow:hidden;
+}
+.x-layout-grid-wrapper{
+
+}
+.x-layout-split{
+    position:absolute;
+    height:5px;
+    width:5px;
+    line-height:1px;
+    font-size:1px;
+    z-index:3;
+    background-color:#c3daf9;
+}
+.x-layout-panel-hd{
+    background-image: url(/static/images/extjs/default/layout/panel-title-light-bg.gif);
+    color: black;
+    border-bottom:1px solid #98c0f4;
+    position:relative;
+}
+.x-layout-panel-hd-text{
+    font:normal 11px tahoma, verdana, helvetica;
+    padding: 4px;
+    padding-left: 4px;
+    display:block;
+	 white-space:nowrap;
+}
+.x-layout-panel-hd-tools{
+    position:absolute;
+    right:0;
+    top:0;
+    text-align:right;
+    padding-top:2px;
+    padding-right:2px;
+    width:60px;
+}
+.x-layout-tools-button{
+    z-index:6;
+    padding:2px;
+    cursor:pointer;
+    float:right;
+}
+.x-layout-tools-button-over{
+    padding:1px;
+    border:1px solid #98c0f4;
+    background-color:white;
+}
+.x-layout-tools-button-inner{
+    height:12px;
+    width:12px;
+    line-height:1px;
+    font-size:1px;
+    background-repeat:no-repeat;
+    background-position:center;
+}
+.x-layout-close{
+    background-image:url(/static/images/extjs/default/layout/panel-close.gif);
+}
+.x-layout-stick{
+    background-image:url(/static/images/extjs/default/layout/stick.gif);
+}
+.x-layout-collapse-west,.x-layout-expand-east{
+    background-image:url(/static/images/extjs/default/layout/collapse.gif);
+}
+.x-layout-expand-west,.x-layout-collapse-east{
+    background-image:url(/static/images/extjs/default/layout/expand.gif);
+}
+.x-layout-collapse-north,.x-layout-expand-south{
+    background-image:url(/static/images/extjs/default/layout/ns-collapse.gif);
+}
+.x-layout-expand-north,.x-layout-collapse-south{
+    background-image:url(/static/images/extjs/default/layout/ns-expand.gif);
+}
+.x-layout-split-h{
+    background-image:url(/static/images/extjs/default/sizer/e-handle.gif);
+    background-position: left;
+}
+.x-layout-split-v{
+    background-image:url(/static/images/extjs/default/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-layout-panel .x-tabs-wrap{
+    background:url(/static/images/extjs/default/layout/gradient-bg.gif);
+}
+.x-layout-panel .x-tabs-body {
+    background-color:white;
+    overflow:auto;height:100%;
+}
+.x-layout-component-panel, .x-layout-nested-layout {
+	position:relative;
+   padding:0;
+	overflow:hidden;
+	width:200px;
+	height:200px;
+}
+.x-layout-nested-layout .x-layout-panel {
+	  border:0 none;
+}
+.x-layout-nested-layout .x-layout-panel-north {
+	  border-bottom:1px solid #98c0f4;
+}
+.x-layout-nested-layout .x-layout-panel-south {
+	  border-top:1px solid #98c0f4;
+}
+.x-layout-nested-layout .x-layout-panel-east {
+	  border-left:1px solid #98c0f4;
+}
+.x-layout-nested-layout .x-layout-panel-west {
+	  border-right:1px solid #98c0f4;
+}
+
+.x-layout-panel-dragover {
+	border: 2px solid #6593cf;
+}
+.x-layout-panel-proxy {
+	background-image: url(/static/images/extjs/default/layout/gradient-bg.gif);
+	background-color:#c3daf9;
+	border:1px dashed #6593cf;
+	z-index:10001;
+	overflow:hidden;
+	position:absolute;
+	left:0;top:0;
+}
+.x-layout-slider {
+	z-index:15;
+	overflow:hidden;
+	position:absolute;
+}
+
+.x-scroller-up, .x-scroller-down {
+	background-color:#c3daf9;
+	border: 1px solid #6593cf;
+	border-top-color: #fff;
+	border-left-color: #fff;
+	border-right:0 none;
+	cursor:pointer;
+	overflow:hidden;
+	line-height:16px;
+}
+.x-scroller-down {
+	border-bottom: 0 none;
+	border-top: 1px solid #6593cf;
+}
+.x-scroller-btn-over {
+	background-color: #d9e8f8;
+}
+.x-scroller-btn-click {
+	background-color: #AECEF7;
+}
+.x-scroller-btn-disabled {
+	cursor:default;
+	background-color: #c3daf9;
+	-moz-opacity: 0.3;
+   opacity:.30;
+   filter: alpha(opacity=30);
+}
+
+/* Reader Layout */
+
+.x-reader .x-layout-panel-north {
+    border:0 none;
+}
+.x-reader .x-layout-panel-center{
+    border:0 none;
+}
+.x-reader .x-layout-nested-layout .x-layout-panel-center{
+    border:1px solid #99bbe8;
+    border-top:0 none;
+}
+.x-reader .x-layout-nested-layout .x-layout-panel-south{
+    border:1px solid #99bbe8;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/menu.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/menu.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,115 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-menu {
+	border:1px solid;
+    border-color: #a3bad9 #8BB8F3 #8BB8F3 #a3bad9;
+    z-index: 15000;
+	background: #fff url(/static/images/extjs/default/menu/menu.gif) repeat-y;
+}
+.ext-ie .x-menu {
+    zoom:1;
+    overflow:hidden;
+}
+.x-menu-list{
+    border:1px solid #fff;
+}
+.x-menu li{
+	line-height:100%;
+}
+.x-menu li.x-menu-sep-li{
+	line-height:1px;
+}
+.x-menu-list-item{
+	font:normal 11px "Segoe UI",tahoma,"Lucida Sans Unicode",arial, sans-serif;
+    white-space: nowrap;
+    -moz-user-select: none;
+	-khtml-user-select: none;
+	display:block;
+	padding:1px;
+}
+.x-menu-item-arrow{
+	background:transparent url(/static/images/extjs/default/menu/menu-parent.gif) no-repeat right;
+}
+.x-menu-sep {
+	display:block;
+	font-size:1px;
+	background:#c3daf9;
+	margin: 3px 3px 3px 32px;
+    height:1px;
+}
+.x-menu-focus {
+	position:absolute;
+	left:0;
+	top:-5px;
+	width:0;
+	height:0;
+    line-height:1px;
+}
+.x-menu-item {
+	display:block;
+	line-height:14px;
+	padding:3px 21px 3px 3px;
+	white-space: nowrap;
+	text-decoration:none;
+	color:#233d6d;
+	-moz-outline: 0 none;
+	outline: 0 none;
+	cursor:pointer;
+}
+.x-menu-item-active {
+	color:#233d6d;
+	background:#c3daf9;
+	border:1px solid #8BB8F3;
+	padding:0;
+}
+.x-menu-item-icon {
+	border: 0 none;
+	height: 16px;
+	padding: 0;
+	vertical-align: middle;
+	width: 16px;
+	margin: 0 11px 0 0;
+    background-position:center;
+}
+
+.x-menu-check-item .x-menu-item-icon{
+	background: transparent url(/static/images/extjs/default/menu/unchecked.gif) no-repeat center;
+}
+
+.x-menu-item-checked .x-menu-item-icon{
+	background-image:url(/static/images/extjs/default/menu/checked.gif);
+}
+.x-menu-group-item .x-menu-item-icon{
+	background: transparent;
+}
+
+.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{
+    background: transparent url(/static/images/extjs/default/menu/group-checked.gif) no-repeat center;
+}
+
+.x-menu-plain {
+	background:#fff;
+}
+.x-menu-date-item{
+	padding:0;
+}
+
+.x-menu .x-color-palette, .x-menu .x-date-picker{
+    margin-left:32px;
+	margin-right:4px;
+}
+.x-menu .x-date-picker{
+    border:1px solid #a3bad9;
+    margin-top:2px;
+    margin-bottom:2px;
+}
+.x-menu-plain .x-color-palette, .x-menu-plain .x-date-picker{
+	margin:0;
+    border:0 none;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/qtips.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/qtips.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,119 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-tip{
+	position: absolute;
+	top: 0;
+    left:0;
+    visibility: hidden;
+	z-index: 20000;
+    border:0 none;
+}
+.x-tip .x-tip-close{
+	background-image: url(/static/images/extjs/default/qtip/close.gif);
+	height: 15px;
+	float:right;
+	width: 15px;
+    margin:0 0 2px 2px;
+    cursor:pointer;
+    display:none;
+}
+.x-tip .x-tip-top {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -12px;
+	height:6px;
+    overflow:hidden;
+}
+.x-tip .x-tip-top-left {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 0;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-top-right {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat right 0;
+	padding-right:6px;
+    zoom:1;
+}
+.x-tip .x-tip-ft {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -18px;
+	height:6px;
+    overflow:hidden;
+}
+.x-tip .x-tip-ft-left {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -6px;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-ft-right {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat right -6px;
+	padding-right:6px;
+    zoom:1;
+}
+.x-tip .x-tip-bd {
+    border:0 none;
+    font: normal 11px tahoma,arial,helvetica,sans-serif;
+}
+.x-tip .x-tip-bd-left {
+	background: #fff url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat 0 -24px;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-bd-right {
+	background: transparent url(/static/images/extjs/default/qtip/tip-sprite.gif) no-repeat right -24px;
+	padding-right:6px;
+    zoom:1;
+}
+
+.x-tip h3 {
+    font: bold 12px tahoma,arial,helvetica,sans-serif;
+    margin:0;
+    padding:2px 2px;
+    color:#222;
+}
+.x-tip .x-tip-bd-inner {
+    margin:0 !important;
+    line-height:14px;
+    color:#222;
+    padding:0;
+    float:left;
+}
+
+
+.x-form-invalid-tip {
+}
+
+.x-form-invalid-tip .x-tip-top {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-top-left {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-top-right {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-ft {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-ft-left {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-ft-right {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-bd-left {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-bd-right {
+	background-image: url(/static/images/extjs/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-bd .x-tip-bd-inner {
+    padding-left:24px;
+    background:transparent url(/static/images/extjs/default/form/exclamation.gif) no-repeat 2px 2px;
+}
+.x-form-invalid-tip .x-tip-bd-inner {
+    padding:2px;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/reset-min.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/reset-min.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,9 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}
\ No newline at end of file

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/resizable.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/resizable.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,143 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-resizable-handle {
+    position:absolute;
+    z-index:100;
+    /* ie needs these */
+    font-size:1px;
+    line-height:6px;
+    overflow:hidden;
+	 background:white;
+	 filter:alpha(opacity=0);
+	 opacity:0;
+	 zoom:1;
+}
+.x-resizable-handle-east{
+    width:6px;
+    cursor:e-resize;
+    right:0;
+    top:0;
+    height:100%;
+}
+.ext-ie .x-resizable-handle-east {
+      margin-right:-1px; /*IE rounding error*/
+}
+.x-resizable-handle-south{
+    width:100%;
+    cursor:s-resize;
+    left:0;
+    bottom:0;
+    height:6px;
+}
+.ext-ie .x-resizable-handle-south {
+     margin-bottom:-1px; /*IE rounding error*/
+}
+.x-resizable-handle-west{
+    width:6px;
+    cursor:w-resize;
+    left:0;
+    top:0;
+    height:100%;
+}
+.x-resizable-handle-north{
+    width:100%;
+    cursor:n-resize;
+    left:0;
+    top:0;
+    height:6px;
+}
+.x-resizable-handle-southeast{
+    width:6px;
+    cursor:se-resize;
+    right:0;
+    bottom:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-northwest{
+    width:6px;
+    cursor:nw-resize;
+    left:0;
+    top:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-northeast{
+    width:6px;
+    cursor:ne-resize;
+    right:0;
+    top:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-southwest{
+    width:6px;
+    cursor:sw-resize;
+    left:0;
+    bottom:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-over .x-resizable-handle, .x-resizable-pinned .x-resizable-handle{
+    filter:alpha(opacity=100);
+	 opacity:1;
+}
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east{
+    background:url(/static/images/extjs/default/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west{
+    background:url(/static/images/extjs/default/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south{
+    background:url(/static/images/extjs/default/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{
+    background:url(/static/images/extjs/default/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+    background:url(/static/images/extjs/default/sizer/se-handle.gif);
+    background-position: top left;
+}
+.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{
+    background:url(/static/images/extjs/default/sizer/nw-handle.gif);
+    background-position:bottom right;
+}
+.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{
+    background:url(/static/images/extjs/default/sizer/ne-handle.gif);
+    background-position: bottom left;
+}
+.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{
+    background:url(/static/images/extjs/default/sizer/sw-handle.gif);
+    background-position: top right;
+}
+.x-resizable-proxy{
+    border: 1px dashed #6593cf;
+    position:absolute;
+    overflow:hidden;
+    visibility:hidden;
+	 left:0;top:0;
+    z-index:50000;
+}
+.x-resizable-overlay{
+    width:100%;
+	 height:100%;
+	 display:none;
+	 position:absolute;
+	 left:0;
+	 top:0;
+	 background:white;
+	 z-index:200000;
+	 -moz-opacity: 0;
+    opacity:0;
+    filter: alpha(opacity=0);
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/tabs.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/tabs.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,134 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-tabs-wrap {
+	border-bottom:1px solid #6593cf;
+	padding-top:2px;
+}
+.x-tabs-strip-wrap{
+	width:100%;	
+}
+.x-tabs-wrap table{
+	position:relative;
+	top:0; left:0;
+}
+.x-tabs-strip td{
+	padding:0;
+	padding-left:2px;
+}
+.x-tabs-strip a, .x-tabs-strip span, .x-tabs-strip em {
+	display:block;
+}
+.x-tabs-strip a {
+	text-decoration:none !important;
+	-moz-outline: none;
+	outline: none;
+	cursor:pointer;
+}
+.x-tabs-strip .x-tabs-text {
+	font:bold 11px tahoma,arial,helvetica;
+	color:#666;
+	overflow:hidden;
+	white-space: nowrap;
+	cursor:pointer;
+	text-overflow: ellipsis;
+}
+.x-tabs-strip .on .x-tabs-text {
+	cursor:default;
+	color:#083772;
+}
+.x-tabs-strip .disabled .x-tabs-text {
+	cursor:default;
+	color:#aaaaaa;
+}
+.x-tabs-strip .x-tabs-inner {
+	 padding:4px 10px;	
+}
+
+.x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat right 0;
+}
+.x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat 0 -100px;
+}
+.x-tabs-strip .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat right -50px;
+}
+.x-tabs-strip .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-sprite.gif) no-repeat 0 -150px;
+}
+
+.x-tabs-strip  a {
+	position:relative;
+	top:1px; left:0;
+}
+.x-tabs-strip .on a {
+	position:relative;
+}
+.x-tabs-strip .on .x-tabs-inner {
+	padding-bottom:5px;
+}
+/** closable tabs */
+.x-tabs-strip .x-tabs-closable .x-tabs-inner{
+	padding-right:22px;
+	position:relative;
+}
+.x-tabs-strip .x-tabs-closable .close-icon{
+	line-height: 1px;
+	font-size:1px;
+	background-image:url(/static/images/extjs/default/layout/tab-close.gif);
+	display:block;
+	position:absolute;
+	right:5px;top:4px;
+	width:11px;height:11px;
+	cursor:pointer;
+}
+.x-tabs-strip .on .close-icon{
+	background-image:url(/static/images/extjs/default/layout/tab-close-on.gif);
+}
+.x-tabs-strip .x-tabs-closable .close-over{
+	background-image:url(/static/images/extjs/default/layout/tab-close-on.gif);
+}
+.x-tabs-body {
+    border:1px solid #6593cf;
+    border-top:0 none;
+}
+.x-tabs-bottom .x-tabs-wrap {
+	border-top:1px solid #6593cf;
+	border-bottom:0 none;
+	padding-top:0;
+	padding-bottom:2px;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-inactive-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-inactive-left-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/default/tabs/tab-btm-left-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip  a {
+	position:relative;
+	top:0; left:0;
+}
+.x-tabs-bottom .x-tabs-strip .on a {
+	margin-top:-1px;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-inner {
+	padding-top:5px;
+}
+
+.x-tabs-bottom .x-tabs-body {
+    border:1px solid #6593cf;
+    border-bottom:0 none;
+}
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/toolbar.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/toolbar.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,160 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-toolbar{
+	border: 1px solid;
+    border-color:#eaf0f7 #eaf0f7 #a9bfd3 #eaf0f7;
+    display: block;
+	padding:2px;
+    background:#d0def0 url(/static/images/extjs/default/layout/panel-title-light-bg.gif) repeat-x;
+}
+.x-toolbar td {
+	vertical-align:middle;
+}
+.mso .x-toolbar, .x-grid-mso .x-toolbar{
+	border: 0 none;
+	background: url(/static/images/extjs/default/grid/mso-hd.gif);
+}
+.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{
+	white-space: nowrap;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-toolbar .x-item-disabled {
+	color:gray;
+	cursor:default;
+	opacity:.6;
+	-moz-opacity:.6;
+	filter:alpha(opacity=60);
+}
+.x-toolbar .x-item-disabled * {
+	color:gray;
+	cursor:default;
+}
+.x-toolbar .x-btn-left{
+	background:none;
+}
+.x-toolbar .x-btn-right{
+	background:none;
+}
+.x-toolbar .x-btn-center{
+	background:none;
+	padding:0 0;
+}
+.x-toolbar .x-btn-menu-text-wrap .x-btn-center button{
+	padding-right:2px;
+}
+.ext-gecko .x-toolbar .x-btn-menu-text-wrap .x-btn-center button{
+	padding-right:0;
+}
+.x-toolbar .x-btn-menu-arrow-wrap .x-btn-center button{
+	padding:0 2px;
+}
+.x-toolbar .x-btn-menu-arrow-wrap .x-btn-center button {
+    width:12px;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat 0 3px;
+}
+.x-toolbar .x-btn-text-icon .x-btn-menu-arrow-wrap .x-btn-center button {
+    width:12px;
+    background:transparent url(/static/images/extjs/default/toolbar/btn-arrow.gif) no-repeat 0 3px;
+}
+.x-toolbar .x-btn-over .x-btn-menu-arrow-wrap .x-btn-center button {
+	background-position: 0 -47px;
+}
+.x-toolbar .x-btn-over .x-btn-left{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 0;
+}
+.x-toolbar .x-btn-over .x-btn-right{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-toolbar .x-btn-over .x-btn-center{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) repeat-x 0 -42px;
+}
+
+.x-toolbar .x-btn-click .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 -63px;
+}
+.x-toolbar .x-btn-click .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) no-repeat 0 -84px;
+}
+.x-toolbar .x-btn-click .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{
+	background:url(/static/images/extjs/default/toolbar/tb-btn-sprite.gif) repeat-x 0 -105px;
+}
+
+.x-toolbar .ytb-text{
+   padding:2px;
+}
+.x-toolbar .ytb-sep {
+	background-image: url(/static/images/extjs/default/grid/grid-split.gif);
+	background-position: center;
+	background-repeat: no-repeat;
+	display: block;
+	font-size: 1px;
+	height: 16px;
+	width:4px;
+	overflow: hidden;
+	cursor:default;
+	margin: 0 2px 0;
+	border:0;
+}
+.x-toolbar .ytb-spacer {
+    width:2px;
+}
+.mso .x-toolbar .ytb-sep, .x-grid-mso .x-toolbar .ytb-sep{
+	background-image: url(/static/images/extjs/default/grid/grid-blue-split.gif);
+}
+
+/* IE refuses to respect the negative margins in the toolbar */
+.ext-ie .x-toolbar .x-form-field-wrap {
+	padding-bottom:1px;
+}
+.ext-ie .x-toolbar .x-form-field-wrap .x-form-trigger {
+	top:1px;
+}
+
+/* Paging Toolbar */
+
+.x-grid-page-number{
+	width:24px;
+	height:14px;
+}
+.x-grid-page-first .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-first.gif);
+}
+.x-grid-loading .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/done.gif);
+}
+.x-grid-page-last .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-last.gif);
+}
+.x-grid-page-next .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-next.gif);
+}
+.x-grid-page-prev .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-prev.gif);
+}
+.x-item-disabled .x-grid-loading .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/loading.gif);
+}
+.x-item-disabled .x-grid-page-first .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-first-disabled.gif);
+}
+.x-item-disabled .x-grid-page-last .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-last-disabled.gif);
+}
+.x-item-disabled .x-grid-page-next .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-next-disabled.gif);
+}
+.x-item-disabled .x-grid-page-prev .x-btn-text{
+	background-image: url(/static/images/extjs/default/grid/page-prev-disabled.gif);
+}
+.x-paging-info {
+    position:absolute;
+    top:8px;
+    right: 8px;
+    color:#15428b;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/tree.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/tree.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,179 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.x-tree-icon, .x-tree-ec-icon, .x-tree-elbow-line, .x-tree-elbow, .x-tree-elbow-end, .x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{
+	border: 0 none;
+	height: 18px;
+	margin: 0;
+	padding: 0;
+	vertical-align: middle;
+	width: 16px;
+    background-repeat: no-repeat;
+}
+.x-tree-node-collapsed .x-tree-node-icon, .x-tree-node-expanded .x-tree-node-icon, .x-tree-node-leaf .x-tree-node-icon{
+	border: 0 none;
+	height: 18px;
+	margin: 0;
+	padding: 0;
+	vertical-align: middle;
+	width: 16px;
+	background-position:center;
+    background-repeat: no-repeat;
+}
+
+/* some default icons for leaf/folder */
+.x-tree-node-collapsed .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/folder.gif);
+}
+.x-tree-node-expanded .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/folder-open.gif);
+}
+.x-tree-node-leaf .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/leaf.gif);
+}
+
+.x-tree-noicon .x-tree-node-icon{
+	width:0; height:0;
+}
+/* loading icon */
+.x-tree-node-loading .x-tree-node-icon{
+	background-image:url(/static/images/extjs/default/tree/loading.gif) !important;
+}
+.x-tree-node-loading a span{
+	 font-style: italic;
+	 color:#444444;
+}
+
+/* Line styles */
+.x-tree-lines .x-tree-elbow{
+	background-image:url(/static/images/extjs/default/tree/elbow.gif);
+}
+.x-tree-lines .x-tree-elbow-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-plus.gif);
+}
+.x-tree-lines .x-tree-elbow-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-minus.gif);
+}
+.x-tree-lines .x-tree-elbow-end{
+	background-image:url(/static/images/extjs/default/tree/elbow-end.gif);
+}
+.x-tree-lines .x-tree-elbow-end-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-plus.gif);
+}
+.x-tree-lines .x-tree-elbow-end-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-minus.gif);
+}
+.x-tree-lines .x-tree-elbow-line{
+	background-image:url(/static/images/extjs/default/tree/elbow-line.gif);
+}
+
+/* No line styles */
+.x-tree-no-lines .x-tree-elbow{
+	background:transparent;
+}
+.x-tree-no-lines .x-tree-elbow-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-plus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-minus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-end{
+	background:transparent;
+}
+.x-tree-no-lines .x-tree-elbow-end-plus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-plus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-end-minus{
+	background-image:url(/static/images/extjs/default/tree/elbow-end-minus-nl.gif);
+}
+.x-tree-no-lines .x-tree-elbow-line{
+	background:transparent;
+}
+
+.x-tree-elbow-plus, .x-tree-elbow-minus, .x-tree-elbow-end-plus, .x-tree-elbow-end-minus{
+	cursor:pointer;
+}
+.ext-ie ul.x-tree-node-ct{
+    font-size:0;
+    line-height:0;
+}
+.x-tree-node{
+	color: black;
+	font: normal 11px arial, tahoma, helvetica, sans-serif;
+	white-space: nowrap;
+}
+.x-tree-node a, .x-dd-drag-ghost a{
+	text-decoration:none;
+	color:black;
+	-khtml-user-select:none;
+	-moz-user-select:none;
+    -kthml-user-focus:normal;
+    -moz-user-focus:normal;
+    -moz-outline: 0 none;
+    outline:0 none;
+}
+.x-tree-node a span, .x-dd-drag-ghost a span{
+	text-decoration:none;
+	color:black;
+	padding:1px 3px 1px 2px;
+}
+.x-tree-node .x-tree-node-disabled a span{
+	color:gray !important;
+}
+.x-tree-node .x-tree-node-disabled .x-tree-node-icon{
+	-moz-opacity: 0.5;
+   opacity:.5;
+   filter: alpha(opacity=50);
+}
+.x-tree-node .x-tree-node-inline-icon{
+	background:transparent;
+}
+.x-tree-node a:hover, .x-dd-drag-ghost a:hover{
+	text-decoration:none;
+}
+.x-tree-node div.x-tree-drag-insert-below{
+ 	 border-bottom:1px dotted #3366cc;
+}
+.x-tree-node div.x-tree-drag-insert-above{
+	 border-top:1px dotted #3366cc;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below{
+ 	 border-bottom:0 none;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above{
+	 border-top:0 none;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{
+ 	 border-bottom:2px solid #3366cc;
+}
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{
+	 border-top:2px solid #3366cc;
+}
+.x-tree-node .x-tree-drag-append a span{
+	 background:#dddddd;
+	 border:1px dotted gray;
+}
+.x-tree-node .x-tree-selected a span{
+	background:#3366cc;
+	color:white;
+}
+.x-dd-drag-ghost .x-tree-node-indent, .x-dd-drag-ghost .x-tree-ec-icon{
+	display:none !important;
+}
+.x-tree-drop-ok-append .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-add.gif);
+}
+.x-tree-drop-ok-above .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-over.gif);
+}
+.x-tree-drop-ok-below .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-under.gif);
+}
+.x-tree-drop-ok-between .x-dd-drop-icon{
+  background-image: url(/static/images/extjs/default/tree/drop-between.gif);
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-aero.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-aero.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,499 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+/* menus */
+.x-menu {
+	border:1px solid;
+    border-color: #96b9e6 #8BB8F3 #8BB8F3 #96b9e6;
+    z-index: 15000;
+	zoom:1;
+    background:#c3daf9;
+    padding:2px;
+    
+}
+.x-menu-list{
+    background: #fafafa;
+    border:1px solid #fff;
+    border-color:#a3bad9;
+}
+.x-menu-item-icon {
+	margin-right:8px;
+}
+.x-menu-sep {
+    margin-left:3px;
+}
+.x-menu-item-active {
+	color:#233d6d;
+	background:#c3daf9;
+	border:1px solid #fff;
+	padding:0;
+}
+
+.x-date-mmenu .x-menu-list{
+    padding:0;
+}
+.x-date-mmenu .x-menu-list{
+    border:0 none;
+}
+
+.x-menu .x-color-palette, .x-menu .x-date-picker{
+    margin-left:26px;
+}
+.x-menu-plain .x-color-palette, .x-menu-plain .x-date-picker{
+	margin:0;
+    border:0 none;
+}
+/**
+* Tabs
+*/
+.x-tabs-wrap, .x-layout-panel .x-tabs-top .x-tabs-wrap {
+   background:#deecfd;
+	border:1px solid #8db2e3;
+	padding-bottom:2px;
+	padding-top:0;
+}
+.x-tabs-strip-wrap{
+	padding-top:1px;
+	background:#cedff5 url(/static/images/extjs/aero/tabs/tab-strip-bg.gif) repeat-x bottom;
+	border-bottom:1px solid #8db2e3;
+}
+.x-tabs-strip .x-tabs-text {
+	color:#15428b;
+	font:bold 11px tahoma,arial,verdana,sans-serif;
+}
+.x-tabs-strip .on .x-tabs-text {
+	cursor:default;
+	color:#15428b;
+}
+.x-tabs-top .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/aero/tabs/tab-sprite.gif) no-repeat right 0;
+}
+.x-tabs-top .x-tabs-strip .on .x-tabs-left,.x-tabs-top .x-tabs-strip .on a:hover .x-tabs-left{
+	 background: url(/static/images/extjs/aero/tabs/tab-sprite.gif) no-repeat 0 -100px;
+}
+.x-tabs-top .x-tabs-strip .x-tabs-right {
+	 background:transparent url(/static/images/extjs/aero/tabs/tab-sprite.gif) no-repeat right -50px;
+}
+.x-tabs-top .x-tabs-strip .x-tabs-left {
+	background:transparent url(/static/images/extjs/aero/tabs/tab-sprite.gif) no-repeat 0 -150px;
+}
+.x-tabs-top .x-tabs-body {
+	border:1px solid #8db2e3;
+	border-top:0 none;
+}
+.x-tabs-bottom .x-tabs-wrap, .x-layout-panel .x-tabs-bottom .x-tabs-wrap {
+   background:#deecfd;
+	border:1px solid #8db2e3;
+	padding-top:2px;
+	padding-bottom:0;
+}
+.x-tabs-bottom .x-tabs-strip-wrap{
+	padding-top:0;
+	padding-bottom:1px;
+	background:#cedff5 url(/static/images/extjs/aero/tabs/tab-strip-btm-bg.gif) repeat-x top;
+	border-top:1px solid #8db2e3;
+	border-bottom:0 none;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-right {
+	background:transparent url(/static/images/extjs/aero/tabs/tab-btm-inactive-right-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-left {
+	background:transparent url(/static/images/extjs/aero/tabs/tab-btm-inactive-left-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-right,.x-tabs-bottom .x-tabs-strip .on a:hover {
+	 background: url(/static/images/extjs/aero/tabs/tab-btm-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-left,.x-tabs-bottom .x-tabs-strip .on a:hover .x-tabs-left {
+	 background: url(/static/images/extjs/aero/tabs/tab-btm-left-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-body {
+	border:1px solid #8db2e3;
+	border-bottom:0 none;
+}
+/*
+* Basic-Dialog 
+*/
+.x-dlg-proxy {
+	background:#C7DFFC;
+	border:1px solid #A5CCF9;
+}
+.x-dlg-shadow{
+	background:#cccccc;
+   opacity:.3;
+   -moz-opacity:.3;
+   filter: alpha(opacity=30);
+}
+.x-dlg {
+	background:transparent;
+}
+.x-dlg .x-dlg-hd {
+	background: url(/static/images/extjs/aero/basic-dialog/hd-sprite.gif) repeat-x 0 -82px;
+	background-color:#aabaca;
+	color:#15428b;
+	zoom:1;
+	padding-top:7px;
+}
+.x-dlg .x-dlg-hd-left {
+	opacity:.85;
+    -moz-opacity:.85;
+    filter:alpha(opacity=80);
+	background: url(/static/images/extjs/aero/basic-dialog/hd-sprite.gif) no-repeat 0 -41px;
+	zoom:1;
+}
+.x-dlg-modal .x-dlg-hd-left {
+	opacity:.75;
+    -moz-opacity:.75;
+    filter:alpha(opacity=70);
+}
+
+.x-dlg .x-dlg-hd-right {
+	background: url(/static/images/extjs/aero/basic-dialog/hd-sprite.gif) no-repeat right 0;
+	zoom:1;
+}
+.x-dlg .x-dlg-dlg-body{
+	padding:0 0 0;
+	position:absolute;
+	top:24px;left:0;
+	z-index:1;
+	border:0 none;
+	background:transparent;
+}
+.x-dlg .x-dlg-bd{
+	background:#fff;
+	border:1px solid #96b9e6;
+}
+.x-dlg .x-dlg-ft{
+	border:0 none;
+	background:transparent;
+	padding-bottom:8px;
+}
+.x-dlg .x-dlg-bg{
+	filter:alpha(opacity=80);
+	opacity:.85; 
+	-moz-opacity:.85; 
+	zoom:1;
+}
+.x-dlg-modal .x-dlg-bg {
+	opacity:.75;
+    -moz-opacity:.75;
+    filter:alpha(opacity=70);
+}
+.x-dlg .x-dlg-bg-center {
+	padding: 2px 7px 7px 7px;
+	background:transparent url(/static/images/extjs/aero/basic-dialog/bg-center.gif) repeat-x bottom;
+	zoom:1;
+}
+.x-dlg .x-dlg-bg-left{
+	padding-left:7px;
+	background:transparent url(/static/images/extjs/aero/basic-dialog/bg-left.gif) no-repeat bottom left;
+	zoom:1;
+}
+.x-dlg .x-dlg-bg-right{
+	padding-right:7px;
+	background:transparent url(/static/images/extjs/aero/basic-dialog/bg-right.gif) no-repeat bottom right;
+	zoom:1;
+}
+.x-dlg-auto-tabs .x-dlg-dlg-body, .x-dlg-auto-layout .x-dlg-dlg-body{
+	background:transparent;
+	border:0 none;
+}
+.x-dlg-auto-tabs .x-dlg-bd, .x-dlg-auto-layout .x-dlg-bd{
+	background:#fff;
+	border:1px solid #e9f3f5;
+}
+.x-dlg-auto-tabs .x-tabs-top .x-tabs-body,.x-dlg-auto-tabs .x-tabs-bottom .x-tabs-body{
+    border-color:#8db2e3;
+}
+.x-dlg-auto-tabs .x-tabs-top .x-tabs-wrap,.x-dlg-auto-tabs .x-tabs-bottom .x-tabs-wrap{
+    border-color:#8db2e3;
+}
+.x-dlg .x-dlg-toolbox {
+    width:50px;
+    height:20px;
+    right:5px;
+    top:5px;
+}
+.x-dlg .x-dlg-close, .x-dlg .x-dlg-collapse {
+	width:21px;
+	height:20px;
+    margin:0;
+}
+.x-dlg .x-dlg-close {
+    background-image:url(/static/images/extjs/aero/basic-dialog/aero-close.gif);
+}
+.x-dlg .x-dlg-collapse {
+    background-image:url(/static/images/extjs/aero/basic-dialog/collapse.gif);
+}
+.x-dlg-collapsed {
+    border-bottom:1px solid #96b9e6;
+}
+.x-dlg .x-dlg-close-over {
+	background-image:url(/static/images/extjs/aero/basic-dialog/aero-close-over.gif);
+}
+.x-dlg .x-dlg-collapse-over {
+	background-image:url(/static/images/extjs/aero/basic-dialog/collapse-over.gif);
+}
+.x-dlg-collapsed .x-dlg-collapse {
+    background-image:url(/static/images/extjs/aero/basic-dialog/expand.gif);
+}
+.x-dlg-collapsed .x-dlg-collapse-over {
+    background-image:url(/static/images/extjs/aero/basic-dialog/expand-over.gif);
+}
+.x-dlg div.x-resizable-handle-east{
+	background-image:url(/static/images/extjs/aero/s.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-south{
+	background-image:url(/static/images/extjs/aero/s.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-west{
+	background-image:url(/static/images/extjs/aero/s.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-southeast{
+	background-image:url(/static/images/extjs/aero/basic-dialog/se-handle.gif);
+	background-position: bottom right;
+	width:9px;
+	height:9px;
+	border:0;
+	right:2px;
+	bottom:2px;
+}
+.x-dlg div.x-resizable-handle-southwest{
+	background-image:url(/static/images/extjs/aero/s.gif);
+	background-position: top right;
+	margin-left:1px;
+	margin-bottom:1px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-north{
+	background-image:url(/static/images/extjs/aero/s.gif);
+	border:0 none;
+}
+
+#x-msg-box .x-dlg-bd{
+	background:#CFE0F5;
+	border:0 none;
+}
+body.x-masked #x-msg-box .x-dlg-bd, body.x-body-masked #x-msg-box .x-dlg-bd{
+	background:#c4d2e3;
+	border:0 none;
+}
+/* BorderLayout */
+
+.x-layout-container{
+    background:#deecfd;
+}
+.x-layout-collapsed{
+    background-color:#deecfd;
+	 border:1px solid #99bbe8;
+}
+.x-layout-collapsed-over{
+	 background-color:#F5F9FE;
+}
+.x-layout-panel{
+    border:1px solid #99bbe8;
+}
+.x-layout-nested-layout .x-layout-panel {
+	  border:0 none;
+}
+.x-layout-split{
+    background-color:#deecfd;
+}
+.x-layout-panel-hd{
+    background: #ebeadb url(/static/images/extjs/aero/grid/grid-hrow.gif) repeat-x;
+    border-bottom:1px solid #99bbe8;
+}
+.x-layout-panel-hd-text {
+	color:#15428b;
+	font:bold 11px tahoma,arial,verdana,sans-serif;
+}
+
+.x-layout-split-h{
+    background:#deecfd;
+}
+.x-layout-split-v{
+    background:#deecfd;
+}
+.x-layout-panel .x-tabs-top .x-tabs-wrap{
+    border:0 none;
+	 border-bottom:1px solid #8db2e3;
+}
+.x-layout-panel .x-tabs-bottom .x-tabs-wrap{
+    border:0 none;
+	 border-top:1px solid #8db2e3;
+}
+
+.x-layout-nested-layout .x-layout-panel-north {
+	  border-bottom:1px solid #99bbe8;
+}
+.x-layout-nested-layout .x-layout-panel-south {
+	  border-top:1px solid #99bbe8;
+}
+.x-layout-nested-layout .x-layout-panel-east {
+	  border-left:1px solid #99bbe8;
+}
+.x-layout-nested-layout .x-layout-panel-west {
+	  border-right:1px solid #99bbe8;
+}
+.x-layout-panel-dragover {
+	border: 2px solid #99bbe8;
+}
+.x-layout-panel-proxy {
+	background-image: url(/static/images/extjs/aero/layout/gradient-bg.gif);
+	background-color:#f3f2e7;
+	border:1px dashed #99bbe8;
+}
+
+.x-layout-container .x-layout-tabs-body{
+	border:0 none;
+}
+/** Resizable */
+
+.x-resizable-proxy{
+    border: 1px dashed #3b5a82;
+}
+
+/* grid */
+.x-grid-hd-text {
+	color:#15428b;
+    font-weight:bold;
+}
+.x-grid-locked .x-grid-body td {
+	background: #FBFDFF;
+	border-right: 1px solid #deecfd;
+	border-bottom: 1px solid #deecfd !important;
+}
+.x-grid-locked .x-grid-body td .x-grid-cell-inner {
+	border-top:0 none;
+}
+.x-grid-locked .x-grid-row-alt td{
+	background: #F5FAFE;
+}
+.x-grid-locked .x-grid-row-selected td{
+	color: #fff !important;
+	background-color: #316ac5 !important;
+}
+.x-grid-hd{
+	border-bottom:0;
+	background:none;
+}
+.x-grid-hd-row{
+	height:auto;
+}
+.x-grid-hd-over {
+	border-bottom:0 none;
+}
+.x-grid-hd-over .x-grid-hd-body{
+	background:none;
+	border-bottom:0 none;
+}
+.x-grid-hd-over .x-grid-hd-body{
+	background-color: transparent;
+	border-bottom:0;
+}
+.x-grid-split {
+	background-image: url(/static/images/extjs/aero/grid/grid-blue-split.gif);
+}
+.x-grid-header{
+	background: url(/static/images/extjs/aero/grid/grid-hrow.gif);
+	border:0 none;
+	border-bottom:1px solid #6f99cf;
+}
+.x-grid-row-alt{
+	background-color: #f5f5f5;
+}
+.x-grid-row-over td, .x-grid-locked .x-grid-row-over td{
+	background:#d9e8fb;
+}
+.x-grid-col {
+	border-right: 1px solid #eee;
+	border-bottom: 1px solid #eee;
+}
+.x-grid-header .x-grid-hd-inner {
+	padding-bottom: 1px;
+}
+.x-grid-header  .x-grid-hd-text {
+	padding-bottom: 3px;
+}
+.x-grid-hd-over .x-grid-hd-inner {
+	border-bottom: 1px solid #316ac5;
+	padding-bottom: 0;
+}
+.x-grid-hd-over .x-grid-hd-text {
+	background: #d5e4f5;
+	border-bottom: 1px solid #fff;
+	padding-bottom: 2px;
+}
+.x-grid-header .sort-asc .x-grid-hd-inner, .x-grid-header .sort-desc .x-grid-hd-inner {
+	border-bottom: 1px solid #316ac5;
+	padding-bottom: 0;
+}
+.x-grid-header .sort-asc  .x-grid-hd-text, .x-grid-header .sort-desc .x-grid-hd-text {
+	border-bottom: 0 none;
+	padding-bottom: 3px;
+}
+.x-grid-header .sort-asc .x-grid-sort-icon {
+	background-image: url(/static/images/extjs/aero/grid/sort_asc.gif);
+}
+.x-grid-header .sort-desc .x-grid-sort-icon {
+	background-image: url(/static/images/extjs/aero/grid/sort_desc.gif);
+}
+.x-dd-drag-proxy .x-grid-hd-inner{
+	background: #ebeadb url(/static/images/extjs/aero/grid/grid-hrow.gif) repeat-x;
+	height:22px;
+	width:120px;
+}
+
+
+.x-grid-locked td.x-grid-row-marker, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker{
+    background: #ebeadb url(/static/images/extjs/aero/grid/grid-hrow.gif) repeat-x 0 0 !important;
+    vertical-align:middle !important;
+    color:black;
+    padding:0;
+    border-top:1px solid white;
+    border-bottom:1px solid #6f99cf !important;
+    border-right:1px solid #6f99cf !important;
+    text-align:center;
+}
+.x-grid-locked td.x-grid-row-marker div, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker div{
+    padding:0 4px;
+    color:#15428b !important;
+    text-align:center;
+}
+
+/** Toolbar */
+.x-toolbar{
+	padding:2px 2px 2px 2px;
+    background:#d0def0 url(/static/images/extjs/default/toolbar/tb-bg.gif) repeat-x;
+}
+
+.x-toolbar .ytb-sep{
+	background-image: url(/static/images/extjs/aero/grid/grid-blue-split.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-left{
+	background:url(/static/images/extjs/aero/toolbar/tb-btn-sprite.gif) no-repeat 0 0;
+}
+.x-toolbar .x-btn-over .x-btn-right{
+	background:url(/static/images/extjs/aero/toolbar/tb-btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-toolbar .x-btn-over .x-btn-center{
+	background:url(/static/images/extjs/aero/toolbar/tb-btn-sprite.gif) repeat-x 0 -42px;
+}
+
+.x-toolbar .x-btn-click .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{
+	background:url(/static/images/extjs/aero/toolbar/tb-btn-sprite.gif) no-repeat 0 -63px;
+}
+.x-toolbar .x-btn-click .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{
+	background:url(/static/images/extjs/aero/toolbar/tb-btn-sprite.gif) no-repeat 0 -84px;
+}
+.x-toolbar .x-btn-click .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{
+	background:url(/static/images/extjs/aero/toolbar/tb-btn-sprite.gif) repeat-x 0 -105px;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-gray.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-gray.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,438 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+
+.ext-el-mask-msg {
+    border:1px solid #aaa;
+    background: #ddd url(/static/images/extjs/default/box/tb.gif) repeat-x 0 -16px;
+}
+.ext-el-mask-msg div {
+    border:1px solid #ccc;
+}
+
+/*
+ Menu
+ */
+.x-menu {
+	border-color: #999 #999 #999 #999;
+    background-image:url(/static/images/extjs/gray/menu/menu.gif);
+}
+.x-menu-item-arrow{
+	background-image:url(/static/images/extjs/gray/menu/menu-parent.gif);
+}
+.x-menu-item {
+	color:#222;
+}
+.x-menu-item-active {
+	background:#ddd;
+    border:1px solid #aaa;
+}
+.x-menu-sep {
+	background:#aaa;
+}
+
+/* grid */
+.x-grid-header{
+	background: #ebeadb url(/static/images/extjs/gray/grid/grid-hrow.gif) repeat-x;
+	overflow:hidden;
+	position:relative;
+	cursor:default;
+	width:100%;
+}
+.x-grid-hd-row{
+	height:22px;
+}
+.x-grid-hd {
+	padding-right:1px;
+}
+.x-grid-hd-over .x-grid-hd-inner {
+	border-bottom: 1px solid #fcc247;
+}
+.x-grid-hd-over .x-grid-hd-text {
+	background: #faf9f4;
+    padding-bottom:1px;
+    border-bottom: 1px solid #f9a900;
+}
+
+.x-grid-hd-text {
+	color:#000000;
+}
+
+.x-grid-col {
+	border-right: 1px solid #f1efe2;
+	border-bottom: 1px solid #f1efe2;
+}
+.x-grid-row-alt{
+	background:#fcfaf6;
+}
+.x-grid-row-over td{
+	background:#f1f1f1;
+}
+
+
+.x-grid-locked .x-grid-body td {
+	background: #f0efe4;
+	border-right: 1px solid #D6D2C2;
+	border-bottom: 1px solid #D6D2C2 !important;
+}
+
+.x-grid-locked .x-grid-header table{
+    border-right:1px solid transparent;
+}
+.x-grid-locked .x-grid-body table{
+    border-right:1px solid #c6c2b2;
+}
+
+.x-grid-bottombar .x-toolbar{
+	border-right:0 none;
+	border-bottom:0 none;
+	border-top:1px solid #f1efe2;
+}
+
+.x-props-grid .x-grid-col-name{
+	 background-color: #f1efe2;
+}
+
+
+
+.x-grid-locked td.x-grid-row-marker, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker{
+    background: #ebeadb url(/static/images/extjs/gray/grid/grid-hrow.gif) repeat-x 0 bottom !important;
+    vertical-align:middle !important;
+    color:black;
+    padding:0;
+    border-top:1px solid white;
+    border-bottom:none !important;
+    border-right:1px solid #d6d2c2 !important;
+    text-align:center;
+}
+.x-grid-locked td.x-grid-row-marker div, .x-grid-locked .x-grid-row-selected td.x-grid-row-marker div{
+    padding:0 4px;
+    color:black !important;
+    text-align:center;
+}
+
+/**
+* Basic-Dialog 
+*/
+.x-dlg-proxy {
+	background-image: url(/static/images/extjs/gray/layout/gradient-bg.gif);
+	background-color:#EAE8D5;
+	border:1px solid #b3b6b0;
+}
+.x-dlg-shadow{
+	background:#aaaaaa;
+}
+.x-dlg-proxy .tabset{
+    background:url(/static/images/extjs/gray/layout/gradient-bg.gif);
+}
+.x-dlg .x-dlg-hd {
+	background: url(/static/images/extjs/gray/basic-dialog/hd-sprite.gif) repeat-x 0 -82px;
+	background-color:#333333;
+}
+.x-dlg .x-dlg-hd-left {
+	background: url(/static/images/extjs/gray/basic-dialog/hd-sprite.gif) no-repeat 0 -41px;
+}
+.x-dlg .x-dlg-hd-right {
+	background: url(/static/images/extjs/gray/basic-dialog/hd-sprite.gif) no-repeat right 0;
+}
+.x-dlg .x-dlg-dlg-body{
+	background:#efefec;
+	border:1px solid #b3b6b0;
+	border-top:0 none;
+}
+.x-dlg .x-tabs-top .x-tabs-body{
+	border:1px solid #b3b6b0;
+	border-top:0 none;
+}
+.x-dlg .x-tabs-bottom .x-tabs-body{
+	border:1px solid #b3b6b0;
+	border-bottom:0 none;
+}
+.x-dlg .x-layout-container  .x-tabs-body{
+	border:0 none;
+}
+.x-dlg .x-dlg-close {
+	background-image:url(/static/images/extjs/gray/basic-dialog/close.gif);
+}
+.x-dlg .x-dlg-collapse {
+    background-image:url(/static/images/extjs/gray/basic-dialog/collapse.gif);
+}
+.x-dlg-collapsed .x-dlg-collapse {
+    background-image:url(/static/images/extjs/gray/basic-dialog/expand.gif);
+}
+.x-dlg div.x-resizable-handle-east{
+	background-image:url(/static/images/extjs/gray/basic-dialog/e-handle.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-south{
+	background-image:url(/static/images/extjs/gray/basic-dialog/s-handle.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-west{
+	background-image:url(/static/images/extjs/gray/basic-dialog/e-handle.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-southeast{
+	background-image:url(/static/images/extjs/gray/basic-dialog/se-handle.gif);
+	background-position: bottom right;
+	width:8px;
+	height:8px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-southwest{
+	background-image:url(/static/images/extjs/gray/sizer/sw-handle-dark.gif);
+	background-position: top right;
+	margin-left:1px;
+	margin-bottom:1px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-north{
+	background-image:url(/static/images/extjs/gray/s.gif);
+	border:0 none;
+}
+
+/** 
+* Tabs
+*/
+.x-tabs-wrap {
+	border-bottom:1px solid #aca899;
+}
+.x-tabs-strip .on .x-tabs-text {
+	cursor:default;
+	color:#333333;
+}
+.x-tabs-top .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/gray/tabs/tab-sprite.gif) no-repeat right 0;
+}
+.x-tabs-top .x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/gray/tabs/tab-sprite.gif) no-repeat 0px -100px;
+}
+.x-tabs-top .x-tabs-strip .x-tabs-right {
+	 background: url(/static/images/extjs/gray/tabs/tab-sprite.gif) no-repeat right -50px;
+}
+.x-tabs-top .x-tabs-strip .x-tabs-left {
+	 background: url(/static/images/extjs/gray/tabs/tab-sprite.gif) no-repeat 0px -150px;
+}
+.x-tabs-strip .x-tabs-closable .close-icon{
+	background-image:url(/static/images/extjs/gray/layout/tab-close.gif);
+}
+.x-tabs-strip .on .close-icon{
+	background-image:url(/static/images/extjs/gray/layout/tab-close-on.gif);
+}
+.x-tabs-strip .x-tabs-closable .close-over{
+	background-image:url(/static/images/extjs/gray/layout/tab-close-on.gif);
+}
+.x-tabs-body {
+    border:1px solid #aca899;
+    border-top:0 none;
+}
+.x-tabs-bottom .x-tabs-wrap {
+	border-bottom:0 none;
+	padding-top:0;
+	border-top:1px solid #aca899;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-right {
+	 background: url(/static/images/extjs/gray/tabs/tab-btm-inactive-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .x-tabs-left {
+	 background: url(/static/images/extjs/gray/tabs/tab-btm-inactive-left-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/gray/tabs/tab-btm-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/gray/tabs/tab-btm-left-bg.gif) no-repeat bottom right;
+}
+
+.x-tabs-bottom .x-tabs-body {
+    border:1px solid #aca899;
+    border-bottom:0 none;
+}
+
+.x-layout-container .x-layout-tabs-body{
+	border:0 none;
+}
+/* QuickTips */
+
+.x-tip .x-tip-top {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-top-left {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-top-right {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft-left {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft-right {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-bd-left {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-bd-right {
+	background-image: url(/static/images/extjs/gray/qtip/tip-sprite.gif);
+}
+
+/* BorderLayout */
+
+.x-layout-container{
+    background-color:#f3f2e7;
+}
+.x-layout-collapsed{
+    background-color:#f3f2e7;
+	 border:1px solid #aca899;
+}
+.x-layout-collapsed-over{
+	 background-color:#fbfbef;
+}
+.x-layout-panel{
+    border:1px solid #aca899;
+}
+.x-layout-nested-layout .x-layout-panel {
+	  border:0 none;
+}
+.x-layout-split{
+    background-color:#f3f2e7;
+}
+.x-layout-panel-hd{
+    background-image: url(/static/images/extjs/gray/layout/panel-title-light-bg.gif);
+    border-bottom:1px solid #aca899;
+}
+.x-layout-tools-button-over{
+    border:1px solid #aca899;
+}
+.x-layout-close{
+    background-image:url(/static/images/extjs/gray/layout/panel-close.gif);
+}
+.x-layout-stick{
+    background-image:url(/static/images/extjs/gray/layout/stick.gif);
+}
+.x-layout-collapse-west,.x-layout-expand-east{
+    background-image:url(/static/images/extjs/gray/layout/collapse.gif);
+}
+.x-layout-expand-west,.x-layout-collapse-east{
+    background-image:url(/static/images/extjs/gray/layout/expand.gif);
+}
+.x-layout-collapse-north,.x-layout-expand-south{
+    background-image:url(/static/images/extjs/gray/layout/ns-collapse.gif);
+}
+.x-layout-expand-north,.x-layout-collapse-south{
+    background-image:url(/static/images/extjs/gray/layout/ns-expand.gif);
+}
+.x-layout-split-h{
+    background-image:url(/static/images/extjs/gray/sizer/e-handle-dark.gif);
+}
+.x-layout-split-v{
+    background-image:url(/static/images/extjs/gray/sizer/s-handle-dark.gif);
+}
+.x-layout-panel .x-tabs-wrap{
+    background:url(/static/images/extjs/gray/layout/gradient-bg.gif);
+}
+.x-layout-nested-layout .x-layout-panel-north {
+	  border-bottom:1px solid #aca899;
+}
+.x-layout-nested-layout .x-layout-panel-south {
+	  border-top:1px solid #aca899;
+}
+.x-layout-nested-layout .x-layout-panel-east {
+	  border-left:1px solid #aca899;
+}
+.x-layout-nested-layout .x-layout-panel-west {
+	  border-right:1px solid #aca899;
+}
+.x-layout-panel-dragover {
+	border: 2px solid #aca899;
+}
+.x-layout-panel-proxy {
+	background-image: url(/static/images/extjs/gray/layout/gradient-bg.gif);
+	background-color:#f3f2e7;
+	border:1px dashed #aca899;
+}
+/** Resizable */
+
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east{
+    background:url(/static/images/extjs/gray/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-west{
+    background:url(/static/images/extjs/gray/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south{
+    background:url(/static/images/extjs/gray/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-north{
+    background:url(/static/images/extjs/gray/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+    background:url(/static/images/extjs/gray/sizer/se-handle.gif);
+    background-position: top left;
+}
+.x-resizable-over .x-resizable-handle-northwest,.x-resizable-pinned .x-resizable-handle-northwest{
+    background:url(/static/images/extjs/gray/sizer/nw-handle.gif);
+    background-position:bottom right;
+}
+.x-resizable-over .x-resizable-handle-northeast,.x-resizable-pinned .x-resizable-handle-northeast{
+    background:url(/static/images/extjs/gray/sizer/ne-handle.gif);
+    background-position: bottom left;
+}
+.x-resizable-over .x-resizable-handle-southwest,.x-resizable-pinned .x-resizable-handle-southwest{
+    background:url(/static/images/extjs/gray/sizer/sw-handle.gif);
+    background-position: top right;
+}
+.x-resizable-proxy{
+    border: 1px dashed #615e55;
+}
+
+/** Toolbar */
+.x-toolbar{
+	border:0 none;
+	background: #efefe3 url(/static/images/extjs/gray/toolbar/gray-bg.gif) repeat-x;
+	padding:3px;
+}
+.x-toolbar .x-btn-over .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{
+	background:url(/static/images/extjs/gray/toolbar/tb-btn-sprite.gif) no-repeat 0 0;
+}
+.x-toolbar .x-btn-over .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{
+	background:url(/static/images/extjs/gray/toolbar/tb-btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-toolbar .x-btn-over .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{
+	background:url(/static/images/extjs/gray/toolbar/tb-btn-sprite.gif) repeat-x 0 -42px;
+}
+.x-toolbar .x-btn-over .x-btn-menu-arrow-wrap .x-btn-center button {
+	background-position: 0 -47px;
+}
+.x-paging-info {
+    color:#222222;
+}
+
+/* combo box */
+.x-combo-list {
+    border:1px solid #999;
+    background:#dddddd;
+}
+.x-combo-list-hd {
+    color:#222;
+    background-image: url(/static/images/extjs/gray/layout/panel-title-light-bg.gif);
+    border-bottom:1px solid #aca899;
+}
+.x-resizable-pinned .x-combo-list-inner {
+    border-bottom:1px solid #aaa;
+}
+.x-combo-list .x-combo-selected{
+	background:#ddd !important;
+    border:1px solid #aaa;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-vista.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/css/extjs/ytheme-vista.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,511 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+.ext-el-mask-msg {
+    border:1px solid #aaa;
+    background: #ddd url(/static/images/extjs/default/box/tb.gif) repeat-x 0 -16px;
+}
+.ext-el-mask-msg div {
+    border:1px solid #ccc;
+}
+/*
+ Menu
+ */
+.x-menu {
+	border-color: #999 #999 #999 #999;
+    background-image:url(/static/images/extjs/gray/menu/menu.gif);
+}
+.x-menu-item-arrow{
+	background-image:url(/static/images/extjs/gray/menu/menu-parent.gif);
+}
+.x-menu-item {
+	color:#222;
+}
+.x-menu-item-active {
+	background:#ddd;
+    border:1px solid #aaa;
+}
+.x-menu-sep {
+	background:#aaa;
+}
+/** 
+* Tabs
+*/
+.x-tabs-wrap {
+	background:#4f4f4f;
+	border-bottom:1px solid #b3b6b0;
+}
+.x-tabs-strip .x-tabs-text {
+	color:white;
+	font-weight:normal;
+}
+.x-tabs-strip .on .x-tabs-text {
+	cursor:default;
+	color:#333333;
+}
+.x-tabs-top .x-tabs-strip a.x-tabs-right {
+	background:transparent url(/static/images/extjs/vista/tabs/tab-sprite.gif) no-repeat right -50px;
+}
+.x-tabs-top .x-tabs-strip a .x-tabs-left{
+	background:transparent url(/static/images/extjs/vista/tabs/tab-sprite.gif) no-repeat 0px -150px;
+}
+.x-tabs-top .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/vista/tabs/tab-sprite.gif) no-repeat right 0;
+}
+.x-tabs-top .x-tabs-strip .on .x-tabs-left{
+	 background: url(/static/images/extjs/vista/tabs/tab-sprite.gif) no-repeat 0px -100px;
+}
+.x-tabs-strip .x-tabs-closable .close-icon{
+	background-image:url(/static/images/extjs/vista/layout/tab-close.gif);
+}
+.x-tabs-strip .on .close-icon{
+	background-image:url(/static/images/extjs/vista/layout/tab-close-on.gif);
+}
+.x-tabs-strip .x-tabs-closable .close-over{
+	background-image:url(/static/images/extjs/vista/layout/tab-close-on.gif);
+}
+.x-tabs-body {
+    border:1px solid #b3b6b0;
+    border-top:0 none;
+}
+
+.x-tabs-bottom .x-tabs-strip {
+	background:#4f4f4f;
+}
+.x-tabs-bottom .x-tabs-strip a.x-tabs-right {
+	background:transparent url(/static/images/extjs/vista/tabs/tab-btm-inactive-right-bg.gif) no-repeat bottom right;
+}
+.x-tabs-bottom .x-tabs-strip a .x-tabs-left{
+	background:transparent url(/static/images/extjs/vista/tabs/tab-btm-inactive-left-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-wrap {
+	border-bottom:0 none;
+	padding-top:0;
+	border-top:1px solid #b3b6b0;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-right {
+	 background: url(/static/images/extjs/vista/tabs/tab-btm-right-bg.gif) no-repeat bottom left;
+}
+.x-tabs-bottom .x-tabs-strip .on .x-tabs-left {
+	 background: url(/static/images/extjs/vista/tabs/tab-btm-left-bg.gif) no-repeat bottom right;
+}
+
+.x-tabs-bottom .x-tabs-body {
+    border:1px solid #b3b6b0;
+    border-bottom:0 none;
+}
+/**
+* Basic-Dialog 
+*/
+.x-dlg-proxy {
+	background:#d3d6d0;
+	border:2px solid #b3b6b0;
+}
+.x-dlg-shadow{
+	background:#cccccc;
+   opacity:.3;
+   -moz-opacity:.3;
+   filter: alpha(opacity=30);
+}
+.x-dlg .x-dlg-hd {
+	background: url(/static/images/extjs/vista/basic-dialog/hd-sprite.gif) repeat-x 0 -82px;
+	background-color:#333333;
+	zoom:1;
+}
+.x-dlg .x-dlg-hd-left {
+	opacity:.95;-moz-opacity:.95;filter:alpha(opacity=90);
+	background: url(/static/images/extjs/vista/basic-dialog/hd-sprite.gif) no-repeat 0 -41px;
+	zoom:1;
+}
+.x-dlg .x-dlg-hd-right {
+	background: url(/static/images/extjs/vista/basic-dialog/hd-sprite.gif) no-repeat right 0;
+	zoom:1;
+}
+.x-dlg .x-dlg-dlg-body{
+	background:#fff;
+	border:0 none;
+	border-top:0 none;
+	padding:0 0px 0px;
+	position:absolute;
+	top:24px;left:0;
+	z-index:1;
+}
+.x-dlg-auto-tabs .x-dlg-dlg-body{
+	background:transparent;
+}
+.x-dlg-auto-tabs .x-tabs-top .x-tabs-wrap{
+	background:transparent;
+}
+.x-dlg .x-dlg-ft{
+	border-top:1px solid #b3b6b0;
+	background:#F0F0F0;
+	padding-bottom:8px;
+}
+.x-dlg .x-dlg-bg{
+	opacity:.90;-moz-opacity:.90;filter:alpha(opacity=85);
+	zoom:1;
+}
+.x-dlg .x-dlg-bg-left,.x-dlg .x-dlg-bg-center,.x-dlg .x-dlg-bg-right{
+}
+.x-dlg .x-dlg-bg-center {
+	padding: 0px 4px 4px 4px;
+	background:transparent url(/static/images/extjs/vista/basic-dialog/bg-center.gif) repeat-x bottom;
+	zoom:1;
+}
+.x-dlg .x-dlg-bg-left{
+	padding-left:4px;
+	background:transparent url(/static/images/extjs/vista/basic-dialog/bg-left.gif) no-repeat bottom left;
+	zoom:1;
+}
+.x-dlg .x-dlg-bg-right{
+	padding-right:4px;
+	background:transparent url(/static/images/extjs/vista/basic-dialog/bg-right.gif) no-repeat bottom right;
+	zoom:1;
+}
+.x-dlg .x-tabs-top .x-tabs-body{
+	border:0 none;
+}
+.x-dlg .x-tabs-bottom .x-tabs-body{
+	border:1px solid #b3b6b0;
+	border-bottom:0 none;
+}
+.x-dlg .x-layout-container  .x-tabs-body{
+	border:0 none;
+}
+.x-dlg .x-dlg-close {
+    background-image:url(/static/images/extjs/vista/basic-dialog/close.gif);
+}
+.x-dlg .x-dlg-collapse {
+    background-image:url(/static/images/extjs/vista/basic-dialog/collapse.gif);
+}
+.x-dlg-collapsed .x-dlg-collapse {
+    background-image:url(/static/images/extjs/vista/basic-dialog/expand.gif);
+}
+.x-dlg div.x-resizable-handle-east{
+	background-image:url(/static/images/extjs/vista/s.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-south{
+	background-image:url(/static/images/extjs/vista/s.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-west{
+	background-image:url(/static/images/extjs/vista/s.gif);
+	border:0 none;
+}
+.x-dlg div.x-resizable-handle-southeast{
+	background-image:url(/static/images/extjs/vista/s.gif);
+	background-position: bottom right;
+	width:8px;
+	height:8px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-southwest{
+	background-image:url(/static/images/extjs/vista/s.gif);
+	background-position: top right;
+	margin-left:1px;
+	margin-bottom:1px;
+	border:0;
+}
+.x-dlg div.x-resizable-handle-north{
+	background-image:url(/static/images/extjs/vista/s.gif);
+	border:0 none;
+}
+
+/* QuickTips */
+
+.x-tip .x-tip-top {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-top-left {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-top-right {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft-left {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft-right {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-bd-left {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-bd-right {
+	background-image: url(/static/images/extjs/vista/qtip/tip-sprite.gif);
+}
+
+.x-tip .x-tip-bd-inner {
+    padding:2px;
+}
+
+/* BorderLayout */
+.x-layout-container{
+    background:#4f4f4f;
+}
+.x-layout-collapsed{
+    background-color:#9f9f9f;
+	 border:1px solid #4c535c;
+}
+.x-layout-collapsed-over{
+	 background-color:#bfbfbf;
+}
+.x-layout-panel{
+    border:1px solid #4c535c;
+}
+.x-layout-nested-layout .x-layout-panel {
+	  border:0 none;
+}
+.x-layout-split{
+    background-color:#f3f2e7;
+}
+.x-layout-panel-hd{
+    background-image: url(/static/images/extjs/vista/layout/panel-title-bg.gif);
+    border-bottom:1px solid #b5bac1;
+    color:white;
+}
+.x-layout-panel-hd-text{
+	color:white;
+}
+.x-layout-tools-button-over{
+    border:1px solid #4c535c;
+	 background:#9f9f9f url(/static/images/extjs/vista/layout/panel-title-bg.gif) repeat-x;
+}
+.x-layout-close{
+    background-image:url(/static/images/extjs/vista/layout/tab-close.gif);
+}
+
+.x-layout-stick{
+    background-image:url(/static/images/extjs/vista/layout/stick.gif);
+}
+.x-layout-collapse-west,.x-layout-expand-east{
+    background-image:url(/static/images/extjs/vista/layout/collapse.gif);
+}
+.x-layout-expand-west,.x-layout-collapse-east{
+    background-image:url(/static/images/extjs/vista/layout/expand.gif);
+}
+.x-layout-collapse-north,.x-layout-expand-south{
+    background-image:url(/static/images/extjs/vista/layout/ns-collapse.gif);
+}
+.x-layout-expand-north,.x-layout-collapse-south{
+    background-image:url(/static/images/extjs/vista/layout/ns-expand.gif);
+}
+.x-layout-split-h{
+    background:#9f9f9f;
+}
+.x-layout-split-v{
+    background:#9f9f9f;
+}
+.x-layout-panel .x-tabs-wrap{
+    background:#4f4f4f;
+}
+.x-layout-nested-layout .x-layout-panel-north {
+	  border-bottom:1px solid #4c535c;
+}
+.x-layout-nested-layout .x-layout-panel-south {
+	  border-top:1px solid #4c535c;
+}
+.x-layout-nested-layout .x-layout-panel-east {
+	  border-left:1px solid #4c535c;
+}
+.x-layout-nested-layout .x-layout-panel-west {
+	  border-right:1px solid #4c535c;
+}
+.x-layout-panel-dragover {
+	border: 2px solid #4c535c;
+}
+.x-layout-panel-proxy {
+	background-image: url(/static/images/extjs/vista/layout/gradient-bg.gif);
+	background-color:#f3f2e7;
+	border:1px dashed #4c535c;
+}
+
+.x-layout-container .x-layout-tabs-body{
+	border:0 none;
+}
+/** Resizable */
+
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east{
+    background:url(/static/images/extjs/vista/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-west{
+    background:url(/static/images/extjs/vista/sizer/e-handle.gif);
+	 background-position: left;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south{
+    background:url(/static/images/extjs/vista/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-north{
+    background:url(/static/images/extjs/vista/sizer/s-handle.gif);
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+    background:url(/static/images/extjs/vista/sizer/se-handle.gif);
+    background-position: top left;
+}
+.x-resizable-over .x-resizable-handle-northwest,.x-resizable-pinned .x-resizable-handle-northwest{
+    background:url(/static/images/extjs/vista/sizer/nw-handle.gif);
+    background-position:bottom right;
+}
+.x-resizable-over .x-resizable-handle-northeast,.x-resizable-pinned .x-resizable-handle-northeast{
+    background:url(/static/images/extjs/vista/sizer/ne-handle.gif);
+    background-position: bottom left;
+}
+.x-resizable-over .x-resizable-handle-southwest,.x-resizable-pinned .x-resizable-handle-southwest{
+    background:url(/static/images/extjs/vista/sizer/sw-handle.gif);
+    background-position: top right;
+}
+.x-resizable-proxy{
+    border: 1px dashed #615e55;
+}
+
+/** Toolbar */
+.x-toolbar{
+	border:0 none;
+	background: #efefe3 url(/static/images/extjs/vista/toolbar/gray-bg.gif) repeat-x;
+	padding:3px;
+}
+.x-toolbar .ytb-button-over{
+	border:1px solid transparent;
+	border-bottom:1px solid #bbbbbb;
+	border-top:1px solid #eeeeee;
+	background:#9f9f9f url(/static/images/extjs/vista/grid/grid-vista-hd.gif) repeat-x;
+}
+
+.x-paging-info {
+    color:#000;
+}
+/* grid */
+.x-grid-topbar .x-toolbar{
+	border:0;
+	border-bottom:1px solid #555;
+}
+.x-grid-bottombar .x-toolbar{
+	border:0;
+	border-top:1px solid #555;
+}
+.x-grid-locked .x-grid-body td {
+	background: #fafafa;
+	border-right: 1px solid #e1e1e1;
+	border-bottom: 1px solid #e1e1e1 !important;
+}
+.x-grid-locked .x-grid-body td .x-grid-cell-inner {
+	border-top:0 none;
+}
+.x-grid-locked .x-grid-row-alt td{
+	background: #f1f1f1;
+}
+.x-grid-locked .x-grid-row-selected td{
+	color: #fff !important;
+	background-color: #316ac5 !important;
+}
+.x-grid-hd{
+	border-bottom:0;
+	background:none;
+}
+.x-grid-hd-row{
+	height:auto;
+}
+.x-grid-split {
+	background-image: url(/static/images/extjs/vista/grid/grid-split.gif);
+}
+.x-grid-header{
+	background: url(/static/images/extjs/vista/grid/grid-vista-hd.gif);
+	border:0 none;
+    border-bottom:1px solid #555;
+}
+.x-grid-row-alt{
+	background-color: #f5f5f5;
+}
+.x-grid-row-over td{
+	background:#eeeeee;
+}
+.x-grid-col {
+	border-right: 1px solid #eee;
+	border-bottom: 1px solid #eee;
+}
+.x-grid-header .x-grid-hd-inner {
+	padding-bottom: 1px;
+}
+.x-grid-header  .x-grid-hd-text {
+	padding-bottom: 3px;
+    color:#333333;
+}
+.x-grid-hd-over .x-grid-hd-inner {
+	border-bottom: 1px solid #555;
+	padding-bottom: 0;
+}
+.x-grid-hd-over .x-grid-hd-text {
+	background-color: #fafafa;
+	border-bottom: 1px solid #555;
+	padding-bottom: 2px;
+}
+.x-grid-header .sort-asc .x-grid-hd-inner, .x-grid-header .sort-desc .x-grid-hd-inner {
+	border-bottom: 1px solid #555;
+	padding-bottom: 0;
+}
+.x-grid-header .sort-asc  .x-grid-hd-text, .x-grid-header .sort-desc .x-grid-hd-text {
+	border-bottom: 1px solid #3b5a82;
+	padding-bottom: 2px;
+}
+.x-dd-drag-proxy .x-grid-hd-inner{
+	background: url(/static/images/extjs/vista/grid/grid-vista-hd.gif) repeat-x;
+	height:22px;
+	width:120px;
+}
+.x-props-grid .x-grid-col-name{
+	 background-color: #eee;
+}
+/* toolbar */
+.x-toolbar .ytb-sep{
+	background-image: url(/static/images/extjs/vista/grid/grid-split.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-left{
+	background:url(/static/images/extjs/vista/toolbar/tb-btn-sprite.gif) no-repeat 0 0px;
+}
+.x-toolbar .x-btn-over .x-btn-right{
+	background:url(/static/images/extjs/vista/toolbar/tb-btn-sprite.gif) no-repeat 0 -21px;
+}
+.x-toolbar .x-btn-over .x-btn-center{
+	background:url(/static/images/extjs/vista/toolbar/tb-btn-sprite.gif) repeat-x 0 -42px;
+}
+
+.x-toolbar .x-btn-click .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{
+	background:url(/static/images/extjs/vista/toolbar/tb-btn-sprite.gif) no-repeat 0 -63px;
+}
+.x-toolbar .x-btn-click .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{
+	background:url(/static/images/extjs/vista/toolbar/tb-btn-sprite.gif) no-repeat 0 -84px;
+}
+.x-toolbar .x-btn-click .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{
+	background:url(/static/images/extjs/vista/toolbar/tb-btn-sprite.gif) repeat-x 0 -105px;
+}
+
+/* combo box */
+.x-combo-list {
+    border:1px solid #999;
+    background:#dddddd;
+}
+.x-combo-list-hd {
+    background-image: url(/static/images/extjs/vista/layout/panel-title-bg.gif);
+    border-bottom:1px solid #b5bac1;
+    color:white;
+}
+.x-resizable-pinned .x-combo-list-inner {
+    border-bottom:1px solid #aaa;
+}
+.x-combo-list .x-combo-selected{
+	background:#ddd !important;
+    border:1px solid #aaa;
+}

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close-over.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/aero-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-center.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-left.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/bg-right.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse-over.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand-over.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/hd-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/basic-dialog/w-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-blue-split.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-hrow.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-split.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/grid-vista-hd.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/pspbrwse.jbf
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort-col-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_asc.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/grid/sort_desc.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/ns-expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/panel-title-light-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close-on.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/layout/tab-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/qtip/bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/s.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/ne-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/nw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/sizer/sw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-inactive-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-btm-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-bg.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/tabs/tab-strip-btm-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/aero/toolbar/tb-btn-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-arrow.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/btn-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/hd-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/progress2.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/basic-dialog/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/corners-blue.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/corners.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/l-blue.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/l.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/r-blue.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/r.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/tb-blue.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/box/tb.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-add.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-no.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/dd/drop-yes.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/date-trigger.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/error-tip-corners.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/exclamation.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/text-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/form/trigger.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/Thumbs.db
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-left-white.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/arrow-right-white.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-bottom.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/col-move-top.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/dirty.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/done.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-no.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/drop-yes.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/footer-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-hd.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-blue-split.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-hrow.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-loading.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-split.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/grid-vista-hd.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-asc.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-desc.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-lock.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/hmenu-unlock.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/invalid_line.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/loading.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/mso-hd.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/nowait.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first-disabled.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-first.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last-disabled.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-last.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next-disabled.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-next.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev-disabled.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/page-prev.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/pick-button.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/refresh.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_asc.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/sort_desc.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/grid/wait.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/ns-expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/panel-title-light-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/stick.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/stuck.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close-on.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/layout/tab-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/checked.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/group-checked.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/menu-parent.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/menu.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/menu/unchecked.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/qtip/tip-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/s.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shadow-lr.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shadow.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/calendar.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/left-btn.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/right-btn.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/shared/warning.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/ne-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/nw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/square.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/sizer/sw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-inactive-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-btm-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tabs/tab-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow-light.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-arrow.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/btn-over-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/gray-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/toolbar/tb-btn-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-add.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-between.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-no.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-over.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-under.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/drop-yes.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus-nl.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-minus.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus-nl.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end-plus.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-end.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-line.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus-nl.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-minus.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus-nl.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow-plus.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/elbow.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/folder-open.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/folder.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/leaf.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/loading.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/default/tree/s.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/dlg-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/hd-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/basic-dialog/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/grid/grid-hrow.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/ns-expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/panel-title-light-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/stick.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close-on.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/layout/tab-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/checked.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/group-checked.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu-parent.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/menu.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/menu/unchecked.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/qtip/bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/qtip/tip-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/s.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/ne-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/nw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/sizer/sw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-inactive-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-btm-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/tabs/tab-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/gray-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/gray/toolbar/tb-btn-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-center.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-left.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/bg-right.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/dlg-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/hd-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/basic-dialog/w-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-split.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/grid/grid-vista-hd.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/gradient-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-collapse.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/ns-expand.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/panel-title-light-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/stick.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close-on.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/layout/tab-close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/qtip/bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/qtip/tip-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/s.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/e-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/ne-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/nw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/s-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/se-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle-dark.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/sizer/sw-handle.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-inactive-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-left-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-btm-right-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/tabs/tab-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/gray-bg.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/images/extjs/vista/toolbar/tb-btn-sprite.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/jquery/ext-jquery-adapter.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/jquery/ext-jquery-adapter.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,12 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+Ext={};window["undefined"]=window["undefined"];Ext.apply=function(o,c,_3){if(_3){Ext.apply(o,_3);}if(o&&c&&typeof c=="object"){for(var p in c){o[p]=c[p];}}return o;};(function(){var _5=0;var ua=navigator.userAgent.toLowerCase();var _7=document.compatMode=="CSS1Compat",_8=ua.indexOf("opera")>-1,_9=(/webkit|khtml/).test(ua),_a=ua.indexOf("msie")>-1,_b=ua.indexOf("msie 7")>-1,_c=!_9&&ua.indexOf("gecko")>-1,_d=_a&&!_7,_e=(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1),_f=(ua.indexOf("macintosh")!=-1||ua.indexOf("mac os x")!=-1);if(_a&&!_b){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}}Ext.apply(Ext,{isStrict:_7,SSL_SECURE_URL:"javascript:false",BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif",emptyFn:function(){},applyIf:function(o,c){if(o&&c){for(var p in c){if(typeof o[p]=="undefined"){o[p]=c[p];}}}return o;},id:function(el,_14){_14=_14||"ext-gen";el=Ext.getDom(el);var id=_14+(++_5);return el?(el.id?el.id:(el.id=id)):id;},extend:function(){var io=function(o){for(var m in o){this[m]=o[m];}};return function(sc,sp,_1b){var F=function(){},scp,spp=sp.prototype;F.prototype=spp;scp=sc.prototype=new F();scp.constructor=sc;sc.superclass=spp;if(spp.constructor==Object.prototype.constructor){spp.constructor=sp;}sc.override=function(o){Ext.override(sc,o);};scp.override=io;Ext.override(sc,_1b);return sc;};}(),override:function(_20,_21){if(_21){var p=_20.prototype;for(var _23 in _21){p[_23]=_21[_23];}}},namespace:function(){var a=arguments,o=null,i,j,d,rt;for(i=0;i<a.length;++i){d=a[i].split(".");rt=d[0];eval("if (typeof "+rt+" == \"undefined\"){"+rt+" = {};} o = "+rt+";");for(j=1;j<d.length;++j){o[d[j]]=o[d[j]]||{};o=o[d[j]];}}},urlEncode:function(o){if(!o){return "";}var buf=[];for(var key in o){var ov=o[key];var _2e=typeof ov;if(_2e=="undefined"){buf.push(encodeURIComponent(key),"=&");}else{if(_2e!="function"&&_2e!="object"){buf.push(encodeURIComponent(key),"=",encodeURIComponent(ov),"&");}else{if(ov instanceof Array){for(var i=0,len=ov.length;i<len;i++){buf.push(encodeURIComponent(key),"=",encodeURIComponent(ov[i]===undefined?"":ov[i]),"&");}}}}}buf.pop();return buf.join("");},urlDecode:function(_31,_32){if(!_31||!_31.length){return {};}var obj={};var _34=_31.split("&");var _35,_36,_37;for(var i=0,len=_34.length;i<len;i++){_35=_34[i].split("=");_36=_35[0];_37=_35[1];if(_32!==true){if(typeof obj[_36]=="undefined"){obj[_36]=_37;}else{if(typeof obj[_36]=="string"){obj[_36]=[obj[_36]];obj[_36].push(_37);}else{obj[_36].push(_37);}}}else{obj[_36]=_37;}}return obj;},each:function(_3a,fn,_3c){if(typeof _3a.length=="undefined"||typeof _3a=="string"){_3a=[_3a];}for(var i=0,len=_3a.length;i<len;i++){if(fn.call(_3c||_3a[i],_3a[i],i,_3a)===false){return i;}}},combine:function(){var as=arguments,l=as.length,r=[];for(var i=0;i<l;i++){var a=as[i];if(a instanceof Array){r=r.concat(a);}else{if(a.length!==undefined&&!a.substr){r=r.concat(Array.prototype.slice.call(a,0));}else{r.push(a);}}}return r;},escapeRe:function(s){return s.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1");},callback:function(cb,_46,_47,_48){if(typeof cb=="function"){if(_48){cb.defer(_48,_46,_47||[]);}else{cb.apply(_46,_47||[]);}}},getDom:function(el){if(!el){return null;}return el.dom?el.dom:(typeof el=="string"?document.getElementById(el):el);},num:function(v,_4b){if(typeof v!="number"){return _4b;}return v;},isOpera:_8,isSafari:_9,isIE:_a,isIE7:_b,isGecko:_c,isBorderBox:_d,isWindows:_e,isMac:_f,useShims:((_a&&!_b)||(_c&&_f))});})();Ext.namespace("Ext","Ext.util","Ext.grid","Ext.dd","Ext.tree","Ext.data","Ext.form","Ext.menu","Ext.state","Ext.lib");Ext.apply(Function.prototype,{createCallback:function(){var _4c=arguments;var _4d=this;return function(){return _4d.apply(window,_4c);};},createDelegate:function(obj,_4f,_50){var _51=this;return function(){var _52=_4f||arguments;if(_50===true){_52=Array.prototype.slice.call(arguments,0);_52=_52.concat(_4f);}else{if(typeof _50=="number"){_52=Array.prototype.slice.call(arguments,0);var _53=[_50,0].concat(_4f);Array.prototype.splice.apply(_52,_53);}}return _51.apply(obj||window,_52);};},defer:function(_54,obj,_56,_57){var fn=this.createDelegate(obj,_56,_57);if(_54){return setTimeout(fn,_54);}fn();return 0;},createSequence:function(fcn,_5a){if(typeof fcn!="function"){return this;}var _5b=this;return function(){var _5c=_5b.apply(this||window,arguments);fcn.apply(_5a||this||window,arguments);return _5c;};},createInterceptor:function(fcn,_5e){if(typeof fcn!="function"){return this;}var _5f=this;return function(){fcn.target=this;fcn.method=_5f;if(fcn.apply(_5e||this||window,arguments)===false){return;}return _5f.apply(this||window,arguments);};}});Ext.applyIf(String,{escape:function(_60){return _60.replace(/('|\\)/g,"\\$1");},leftPad:function(val,_62,ch){var _64=new String(val);if(ch==null){ch=" ";}while(_64.length<_62){_64=ch+_64;}return _64;},format:function(_65){var _66=Array.prototype.slice.call(arguments,1);return _65.replace(/\{(\d+)\}/g,function(m,i){return _66[i];});}});String.prototype.toggle=function(_69,_6a){return this==_69?_6a:_69;};Ext.applyIf(Number.prototype,{constrain:function(min,max){return Math.min(Math.max(this,min),max);}});Ext.applyIf(Array.prototype,{indexOf:function(o){for(var i=0,len=this.length;i<len;i++){if(this[i]==o){return i;}}return -1;},remove:function(o){var _71=this.indexOf(o);if(_71!=-1){this.splice(_71,1);}}});Date.prototype.getElapsed=function(_72){return Math.abs((_72||new Date()).getTime()-this.getTime());};
+
+if(typeof jQuery=="undefined"){throw "Unable to load Ext, jQuery not found.";}(function(){Ext.lib.Dom={getViewWidth:function(_1){return _1?Math.max(jQuery(document).width(),jQuery(window).width()):jQuery(window).width();},getViewHeight:function(_2){return _2?Math.max(jQuery(document).height(),jQuery(window).height()):jQuery(window).height();},isAncestor:function(p,c){p=Ext.getDom(p);c=Ext.getDom(c);if(!p||!c){return false;}if(p.contains&&!Ext.isSafari){return p.contains(c);}else{if(p.compareDocumentPosition){return !!(p.compareDocumentPosition(c)&16);}else{var _5=c.parentNode;while(_5){if(_5==p){return true;}else{if(!_5.tagName||_5.tagName.toUpperCase()=="HTML"){return false;}}_5=_5.parentNode;}return false;}}},getRegion:function(el){return Ext.lib.Region.getRegion(el);},getY:function(el){return jQuery(el).offset().top;},getX:function(el){return jQuery(el).offset().left;},getXY:function(el){var o=jQuery(el).offset();return [o.left,o.top];},setXY:function(el,xy){el=Ext.fly(el,"_setXY");el.position();var _d=el.translatePoints(xy);if(xy[0]!==false){el.dom.style.left=_d.left+"px";}if(xy[1]!==false){el.dom.style.top=_d.top+"px";}},setX:function(el,x){this.setXY(el,[x,false]);},setY:function(el,y){this.setXY(el,[false,y]);}};Ext.lib.Event={getPageX:function(e){e=e.browserEvent||e;return e.pageX;},getPageY:function(e){e=e.browserEvent||e;return e.pageY;},getXY:function(e){e=e.browserEvent||e;return [e.pageX,e.pageY];},getTarget:function(e){return e.target;},on:function(el,_17,fn,_19,_1a){jQuery(el).bind(_17,fn);},un:function(el,_1c,fn){jQuery(el).unbind(_1c,fn);},purgeElement:function(el){jQuery(el).unbind();},preventDefault:function(e){e=e.browserEvent||e;e.preventDefault();},stopPropagation:function(e){e=e.browserEvent||e;e.stopPropagation();},stopEvent:function(e){e=e.browserEvent||e;e.preventDefault();e.stopPropagation();},onAvailable:function(id,fn,_24){var _25=new Date();var f=function(){if(_25.getElapsed()>10000){clearInterval(iid);}var el=document.getElementById(id);if(el){clearInterval(iid);fn.call(_24||window,el);}};var iid=setInterval(f,50);},resolveTextNode:function(_29){if(_29&&3==_29.nodeType){return _29.parentNode;}else{return _29;}},getRelatedTarget:function(ev){ev=ev.browserEvent||ev;var t=ev.relatedTarget;if(!t){if(ev.type=="mouseout"){t=ev.toElement;}else{if(ev.type=="mouseover"){t=ev.fromElement;}}}return this.resolveTextNode(t);}};Ext.lib.Ajax=function(){var _2c=function(cb){return function(xhr,_2f){if((_2f=="error"||_2f=="timeout")&&cb.failure){cb.failure.call(cb.scope||window,{responseText:xhr.responseText,responseXML:xhr.responseXML,argument:cb.argument});}else{if(cb.success){cb.success.call(cb.scope||window,{responseText:xhr.responseText,responseXML:xhr.responseXML,argument:cb.argument});}}};};return {request:function(_30,uri,cb,_33){jQuery.ajax({type:_30,url:uri,data:_33,timeout:cb.timeout,complete:_2c(cb)});},formRequest:function(_34,uri,cb,_37,_38,_39){jQuery.ajax({type:"POST",url:uri,data:jQuery(_34).formSerialize()+(_37?"&"+_37:""),timeout:cb.timeout,complete:_2c(cb)});},isCallInProgress:function(_3a){return false;},abort:function(_3b){return false;},serializeForm:function(_3c){return jQuery(_3c.dom||_3c).formSerialize();}};}();Ext.lib.Anim=function(){var _3d=function(cb,_3f){var _40=true;return {stop:function(_41){},isAnimated:function(){return _40;},proxyCallback:function(){_40=false;Ext.callback(cb,_3f);}};};return {scroll:function(el,_43,_44,_45,cb,_47){var _48=_3d(cb,_47);el=Ext.getDom(el);el.scrollLeft=_43.to[0];el.scrollTop=_43.to[1];_48.proxyCallback();return _48;},motion:function(el,_4a,_4b,_4c,cb,_4e){return this.run(el,_4a,_4b,_4c,cb,_4e);},color:function(el,_50,_51,_52,cb,_54){var _55=_3d(cb,_54);_55.proxyCallback();return _55;},run:function(el,_57,_58,_59,cb,_5b,_5c){var _5d=_3d(cb,_5b);var o={};for(var k in _57){switch(k){case "points":var by,pts,e=Ext.fly(el,"_animrun");e.position();if(by=_57.points.by){var xy=e.getXY();pts=e.translatePoints([xy[0]+by[0],xy[1]+by[1]]);}else{pts=e.translatePoints(_57.points.to);}o.left=pts.left;o.top=pts.top;if(!parseInt(e.getStyle("left"),10)){e.setLeft(0);}if(!parseInt(e.getStyle("top"),10)){e.setTop(0);}break;case "width":o.width=_57.width.to;break;case "height":o.height=_57.height.to;break;case "opacity":o.opacity=_57.opacity.to;break;default:o[k]=_57[k].to;break;}}jQuery(el).animate(o,_58*1000,undefined,_5d.proxyCallback);return _5d;}};}();Ext.lib.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};Ext.lib.Region.prototype={contains:function(_68){return (_68.left>=this.left&&_68.right<=this.right&&_68.top>=this.top&&_68.bottom<=this.bottom);},getArea:function(){return ((this.bottom-this.top)*(this.right-this.left));},intersect:function(_69){var t=Math.max(this.top,_69.top);var r=Math.min(this.right,_69.right);var b=Math.min(this.bottom,_69.bottom);var l=Math.max(this.left,_69.left);if(b>=t&&r>=l){return new Ext.lib.Region(t,r,b,l);}else{return null;}},union:function(_6e){var t=Math.min(this.top,_6e.top);var r=Math.max(this.right,_6e.right);var b=Math.max(this.bottom,_6e.bottom);var l=Math.min(this.left,_6e.left);return new Ext.lib.Region(t,r,b,l);},adjust:function(t,l,b,r){this.top+=t;this.left+=l;this.right+=r;this.bottom+=b;return this;}};Ext.lib.Region.getRegion=function(el){var p=Ext.lib.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new Ext.lib.Region(t,r,b,l);};Ext.lib.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];}this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};Ext.lib.Point.prototype=new Ext.lib.Region();if(Ext.isIE){jQuery(window).unload(function(){var p=Function.prototype;delete p.createSequence;delete p.defer;delete p.createDelegate;delete p.createCallback;delete p.createInterceptor;});}})();
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/prototype/ext-prototype-adapter.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/prototype/ext-prototype-adapter.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,12 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+Ext={};window["undefined"]=window["undefined"];Ext.apply=function(o,c,_3){if(_3){Ext.apply(o,_3);}if(o&&c&&typeof c=="object"){for(var p in c){o[p]=c[p];}}return o;};(function(){var _5=0;var ua=navigator.userAgent.toLowerCase();var _7=document.compatMode=="CSS1Compat",_8=ua.indexOf("opera")>-1,_9=(/webkit|khtml/).test(ua),_a=ua.indexOf("msie")>-1,_b=ua.indexOf("msie 7")>-1,_c=!_9&&ua.indexOf("gecko")>-1,_d=_a&&!_7,_e=(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1),_f=(ua.indexOf("macintosh")!=-1||ua.indexOf("mac os x")!=-1);if(_a&&!_b){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}}Ext.apply(Ext,{isStrict:_7,SSL_SECURE_URL:"javascript:false",BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif",emptyFn:function(){},applyIf:function(o,c){if(o&&c){for(var p in c){if(typeof o[p]=="undefined"){o[p]=c[p];}}}return o;},id:function(el,_14){_14=_14||"ext-gen";el=Ext.getDom(el);var id=_14+(++_5);return el?(el.id?el.id:(el.id=id)):id;},extend:function(){var io=function(o){for(var m in o){this[m]=o[m];}};return function(sc,sp,_1b){var F=function(){},scp,spp=sp.prototype;F.prototype=spp;scp=sc.prototype=new F();scp.constructor=sc;sc.superclass=spp;if(spp.constructor==Object.prototype.constructor){spp.constructor=sp;}sc.override=function(o){Ext.override(sc,o);};scp.override=io;Ext.override(sc,_1b);return sc;};}(),override:function(_20,_21){if(_21){var p=_20.prototype;for(var _23 in _21){p[_23]=_21[_23];}}},namespace:function(){var a=arguments,o=null,i,j,d,rt;for(i=0;i<a.length;++i){d=a[i].split(".");rt=d[0];eval("if (typeof "+rt+" == \"undefined\"){"+rt+" = {};} o = "+rt+";");for(j=1;j<d.length;++j){o[d[j]]=o[d[j]]||{};o=o[d[j]];}}},urlEncode:function(o){if(!o){return "";}var buf=[];for(var key in o){var ov=o[key];var _2e=typeof ov;if(_2e=="undefined"){buf.push(encodeURIComponent(key),"=&");}else{if(_2e!="function"&&_2e!="object"){buf.push(encodeURIComponent(key),"=",encodeURIComponent(ov),"&");}else{if(ov instanceof Array){for(var i=0,len=ov.length;i<len;i++){buf.push(encodeURIComponent(key),"=",encodeURIComponent(ov[i]===undefined?"":ov[i]),"&");}}}}}buf.pop();return buf.join("");},urlDecode:function(_31,_32){if(!_31||!_31.length){return {};}var obj={};var _34=_31.split("&");var _35,_36,_37;for(var i=0,len=_34.length;i<len;i++){_35=_34[i].split("=");_36=_35[0];_37=_35[1];if(_32!==true){if(typeof obj[_36]=="undefined"){obj[_36]=_37;}else{if(typeof obj[_36]=="string"){obj[_36]=[obj[_36]];obj[_36].push(_37);}else{obj[_36].push(_37);}}}else{obj[_36]=_37;}}return obj;},each:function(_3a,fn,_3c){if(typeof _3a.length=="undefined"||typeof _3a=="string"){_3a=[_3a];}for(var i=0,len=_3a.length;i<len;i++){if(fn.call(_3c||_3a[i],_3a[i],i,_3a)===false){return i;}}},combine:function(){var as=arguments,l=as.length,r=[];for(var i=0;i<l;i++){var a=as[i];if(a instanceof Array){r=r.concat(a);}else{if(a.length!==undefined&&!a.substr){r=r.concat(Array.prototype.slice.call(a,0));}else{r.push(a);}}}return r;},escapeRe:function(s){return s.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1");},callback:function(cb,_46,_47,_48){if(typeof cb=="function"){if(_48){cb.defer(_48,_46,_47||[]);}else{cb.apply(_46,_47||[]);}}},getDom:function(el){if(!el){return null;}return el.dom?el.dom:(typeof el=="string"?document.getElementById(el):el);},num:function(v,_4b){if(typeof v!="number"){return _4b;}return v;},isOpera:_8,isSafari:_9,isIE:_a,isIE7:_b,isGecko:_c,isBorderBox:_d,isWindows:_e,isMac:_f,useShims:((_a&&!_b)||(_c&&_f))});})();Ext.namespace("Ext","Ext.util","Ext.grid","Ext.dd","Ext.tree","Ext.data","Ext.form","Ext.menu","Ext.state","Ext.lib");Ext.apply(Function.prototype,{createCallback:function(){var _4c=arguments;var _4d=this;return function(){return _4d.apply(window,_4c);};},createDelegate:function(obj,_4f,_50){var _51=this;return function(){var _52=_4f||arguments;if(_50===true){_52=Array.prototype.slice.call(arguments,0);_52=_52.concat(_4f);}else{if(typeof _50=="number"){_52=Array.prototype.slice.call(arguments,0);var _53=[_50,0].concat(_4f);Array.prototype.splice.apply(_52,_53);}}return _51.apply(obj||window,_52);};},defer:function(_54,obj,_56,_57){var fn=this.createDelegate(obj,_56,_57);if(_54){return setTimeout(fn,_54);}fn();return 0;},createSequence:function(fcn,_5a){if(typeof fcn!="function"){return this;}var _5b=this;return function(){var _5c=_5b.apply(this||window,arguments);fcn.apply(_5a||this||window,arguments);return _5c;};},createInterceptor:function(fcn,_5e){if(typeof fcn!="function"){return this;}var _5f=this;return function(){fcn.target=this;fcn.method=_5f;if(fcn.apply(_5e||this||window,arguments)===false){return;}return _5f.apply(this||window,arguments);};}});Ext.applyIf(String,{escape:function(_60){return _60.replace(/('|\\)/g,"\\$1");},leftPad:function(val,_62,ch){var _64=new String(val);if(ch==null){ch=" ";}while(_64.length<_62){_64=ch+_64;}return _64;},format:function(_65){var _66=Array.prototype.slice.call(arguments,1);return _65.replace(/\{(\d+)\}/g,function(m,i){return _66[i];});}});String.prototype.toggle=function(_69,_6a){return this==_69?_6a:_69;};Ext.applyIf(Number.prototype,{constrain:function(min,max){return Math.min(Math.max(this,min),max);}});Ext.applyIf(Array.prototype,{indexOf:function(o){for(var i=0,len=this.length;i<len;i++){if(this[i]==o){return i;}}return -1;},remove:function(o){var _71=this.indexOf(o);if(_71!=-1){this.splice(_71,1);}}});Date.prototype.getElapsed=function(_72){return Math.abs((_72||new Date()).getTime()-this.getTime());};
+
+(function(){var _1;Ext.lib.Dom={getViewWidth:function(_2){return _2?this.getDocumentWidth():this.getViewportWidth();},getViewHeight:function(_3){return _3?this.getDocumentHeight():this.getViewportHeight();},getDocumentHeight:function(){var _4=(document.compatMode!="CSS1Compat")?document.body.scrollHeight:document.documentElement.scrollHeight;return Math.max(_4,this.getViewportHeight());},getDocumentWidth:function(){var _5=(document.compatMode!="CSS1Compat")?document.body.scrollWidth:document.documentElement.scrollWidth;return Math.max(_5,this.getViewportWidth());},getViewportHeight:function(){var _6=self.innerHeight;var _7=document.compatMode;if((_7||Ext.isIE)&&!Ext.isOpera){_6=(_7=="CSS1Compat")?document.documentElement.clientHeight:document.body.clientHeight;}return _6;},getViewportWidth:function(){var _8=self.innerWidth;var _9=document.compatMode;if(_9||Ext.isIE){_8=(_9=="CSS1Compat")?document.documentElement.clientWidth:document.body.clientWidth;}return _8;},isAncestor:function(p,c){p=Ext.getDom(p);c=Ext.getDom(c);if(!p||!c){return false;}if(p.contains&&!Ext.isSafari){return p.contains(c);}else{if(p.compareDocumentPosition){return !!(p.compareDocumentPosition(c)&16);}else{var _c=c.parentNode;while(_c){if(_c==p){return true;}else{if(!_c.tagName||_c.tagName.toUpperCase()=="HTML"){return false;}}_c=_c.parentNode;}return false;}}},getRegion:function(el){return Ext.lib.Region.getRegion(el);},getY:function(el){return this.getXY(el)[1];},getX:function(el){return this.getXY(el)[0];},getXY:function(el){var p,pe,b,_14,bd=document.body;el=Ext.getDom(el);if(el.getBoundingClientRect){b=el.getBoundingClientRect();_14=fly(document).getScroll();return [b.left+_14.left,b.top+_14.top];}else{var x=el.offsetLeft,y=el.offsetTop;p=el.offsetParent;var _18=false;if(p!=el){while(p){x+=p.offsetLeft;y+=p.offsetTop;if(Ext.isSafari&&!_18&&fly(p).getStyle("position")=="absolute"){_18=true;}if(Ext.isGecko){pe=fly(p);var bt=parseInt(pe.getStyle("borderTopWidth"),10)||0;var bl=parseInt(pe.getStyle("borderLeftWidth"),10)||0;x+=bl;y+=bt;if(p!=el&&pe.getStyle("overflow")!="visible"){x+=bl;y+=bt;}}p=p.offsetParent;}}if(Ext.isSafari&&(_18||fly(el).getStyle("position")=="absolute")){x-=bd.offsetLeft;y-=bd.offsetTop;}}p=el.parentNode;while(p&&p!=bd){if(!Ext.isOpera||(Ext.isOpera&&p.tagName!="TR"&&fly(p).getStyle("display")!="inline")){x-=p.scrollLeft;y-=p.scrollTop;}p=p.parentNode;}return [x,y];},setXY:function(el,xy){el=Ext.fly(el,"_setXY");el.position();var pts=el.translatePoints(xy);if(xy[0]!==false){el.dom.style.left=pts.left+"px";}if(xy[1]!==false){el.dom.style.top=pts.top+"px";}},setX:function(el,x){this.setXY(el,[x,false]);},setY:function(el,y){this.setXY(el,[false,y]);}};Ext.lib.Event={getPageX:function(e){return Event.pointerX(e.browserEvent||e);},getPageY:function(e){return Event.pointerY(e.browserEvent||e);},getXY:function(e){e=e.browserEvent||e;return [Event.pointerX(e),Event.pointerY(e)];},getTarget:function(e){return Event.element(e.browserEvent||e);},resolveTextNode:function(_26){if(_26&&3==_26.nodeType){return _26.parentNode;}else{return _26;}},getRelatedTarget:function(ev){ev=ev.browserEvent||ev;var t=ev.relatedTarget;if(!t){if(ev.type=="mouseout"){t=ev.toElement;}else{if(ev.type=="mouseover"){t=ev.fromElement;}}}return this.resolveTextNode(t);},on:function(el,_2a,fn){Event.observe(el,_2a,fn,false);},un:function(el,_2d,fn){Event.stopObserving(el,_2d,fn,false);},purgeElement:function(el){},preventDefault:function(e){e=e.browserEvent||e;if(e.preventDefault){e.preventDefault();}else{e.returnValue=false;}},stopPropagation:function(e){e=e.browserEvent||e;if(e.stopPropagation){e.stopPropagation();}else{e.cancelBubble=true;}},stopEvent:function(e){Event.stop(e.browserEvent||e);},onAvailable:function(el,fn,_35,_36){var _37=new Date(),iid;var f=function(){if(_37.getElapsed()>10000){clearInterval(iid);}var el=document.getElementById(id);if(el){clearInterval(iid);fn.call(_35||window,el);}};iid=setInterval(f,50);}};Ext.lib.Ajax=function(){var _3b=function(cb){return cb.success?function(xhr){cb.success.call(cb.scope||window,{responseText:xhr.responseText,responseXML:xhr.responseXML,argument:cb.argument});}:Ext.emptyFn;};var _3e=function(cb){return cb.failure?function(xhr){cb.failure.call(cb.scope||window,{responseText:xhr.responseText,responseXML:xhr.responseXML,argument:cb.argument});}:Ext.emptyFn;};return {request:function(_41,uri,cb,_44){new Ajax.Request(uri,{method:_41,parameters:_44||"",timeout:cb.timeout,onSuccess:_3b(cb),onFailure:_3e(cb)});},formRequest:function(_45,uri,cb,_48,_49,_4a){new Ajax.Request(uri,{method:"POST",parameters:Form.serialize(_45)+(_48?"&"+_48:""),timeout:cb.timeout,onSuccess:_3b(cb),onFailure:_3e(cb)});},isCallInProgress:function(_4b){return false;},abort:function(_4c){return false;},serializeForm:function(_4d){return Form.serialize(_4d.dom||_4d,true);}};}();Ext.lib.Anim=function(){var _4e={easeOut:function(pos){return 1-Math.pow(1-pos,2);},easeIn:function(pos){return 1-Math.pow(1-pos,2);}};var _51=function(cb,_53){return {stop:function(_54){this.effect.cancel();},isAnimated:function(){return this.effect.state=="running";},proxyCallback:function(){Ext.callback(cb,_53);}};};return {scroll:function(el,_56,_57,_58,cb,_5a){var _5b=_51(cb,_5a);el=Ext.getDom(el);el.scrollLeft=_56.to[0];el.scrollTop=_56.to[1];_5b.proxyCallback();return _5b;},motion:function(el,_5d,_5e,_5f,cb,_61){return this.run(el,_5d,_5e,_5f,cb,_61);},color:function(el,_63,_64,_65,cb,_67){return this.run(el,_63,_64,_65,cb,_67);},run:function(el,_69,_6a,_6b,cb,_6d,_6e){var o={};for(var k in _69){switch(k){case "points":var by,pts,e=Ext.fly(el,"_animrun");e.position();if(by=_69.points.by){var xy=e.getXY();pts=e.translatePoints([xy[0]+by[0],xy[1]+by[1]]);}else{pts=e.translatePoints(_69.points.to);}o.left=pts.left+"px";o.top=pts.top+"px";break;case "width":o.width=_69.width.to+"px";break;case "height":o.height=_69.height.to+"px";break;case "opacity":o.opacity=String(_69.opacity.to);break;default:o[k]=String(_69[k].to);break;}}var _75=_51(cb,_6d);_75.effect=new Effect.Morph(Ext.id(el),{duration:_6a,afterFinish:_75.proxyCallback,transition:_4e[_6b]||Effect.Transitions.linear,style:o});return _75;}};}();function fly(el){if(!_1){_1=new Ext.Element.Flyweight();}_1.dom=el;return _1;}Ext.lib.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};Ext.lib.Region.prototype={contains:function(_7b){return (_7b.left>=this.left&&_7b.right<=this.right&&_7b.top>=this.top&&_7b.bottom<=this.bottom);},getArea:function(){return ((this.bottom-this.top)*(this.right-this.left));},intersect:function(_7c){var t=Math.max(this.top,_7c.top);var r=Math.min(this.right,_7c.right);var b=Math.min(this.bottom,_7c.bottom);var l=Math.max(this.left,_7c.left);if(b>=t&&r>=l){return new Ext.lib.Region(t,r,b,l);}else{return null;}},union:function(_81){var t=Math.min(this.top,_81.top);var r=Math.max(this.right,_81.right);var b=Math.max(this.bottom,_81.bottom);var l=Math.min(this.left,_81.left);return new Ext.lib.Region(t,r,b,l);},adjust:function(t,l,b,r){this.top+=t;this.left+=l;this.right+=r;this.bottom+=b;return this;}};Ext.lib.Region.getRegion=function(el){var p=Ext.lib.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new Ext.lib.Region(t,r,b,l);};Ext.lib.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];}this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};Ext.lib.Point.prototype=new Ext.lib.Region();if(Ext.isIE){Event.observe(window,"unload",function(){var p=Function.prototype;delete p.createSequence;delete p.defer;delete p.createDelegate;delete p.createCallback;delete p.createInterceptor;});}})();
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/ext-yui-adapter.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/ext-yui-adapter.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,12 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+Ext={};window["undefined"]=window["undefined"];Ext.apply=function(o,c,_3){if(_3){Ext.apply(o,_3);}if(o&&c&&typeof c=="object"){for(var p in c){o[p]=c[p];}}return o;};(function(){var _5=0;var ua=navigator.userAgent.toLowerCase();var _7=document.compatMode=="CSS1Compat",_8=ua.indexOf("opera")>-1,_9=(/webkit|khtml/).test(ua),_a=ua.indexOf("msie")>-1,_b=ua.indexOf("msie 7")>-1,_c=!_9&&ua.indexOf("gecko")>-1,_d=_a&&!_7,_e=(ua.indexOf("windows")!=-1||ua.indexOf("win32")!=-1),_f=(ua.indexOf("macintosh")!=-1||ua.indexOf("mac os x")!=-1);if(_a&&!_b){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}}Ext.apply(Ext,{isStrict:_7,SSL_SECURE_URL:"javascript:false",BLANK_IMAGE_URL:"http:/"+"/extjs.com/s.gif",emptyFn:function(){},applyIf:function(o,c){if(o&&c){for(var p in c){if(typeof o[p]=="undefined"){o[p]=c[p];}}}return o;},id:function(el,_14){_14=_14||"ext-gen";el=Ext.getDom(el);var id=_14+(++_5);return el?(el.id?el.id:(el.id=id)):id;},extend:function(){var io=function(o){for(var m in o){this[m]=o[m];}};return function(sc,sp,_1b){var F=function(){},scp,spp=sp.prototype;F.prototype=spp;scp=sc.prototype=new F();scp.constructor=sc;sc.superclass=spp;if(spp.constructor==Object.prototype.constructor){spp.constructor=sp;}sc.override=function(o){Ext.override(sc,o);};scp.override=io;Ext.override(sc,_1b);return sc;};}(),override:function(_20,_21){if(_21){var p=_20.prototype;for(var _23 in _21){p[_23]=_21[_23];}}},namespace:function(){var a=arguments,o=null,i,j,d,rt;for(i=0;i<a.length;++i){d=a[i].split(".");rt=d[0];eval("if (typeof "+rt+" == \"undefined\"){"+rt+" = {};} o = "+rt+";");for(j=1;j<d.length;++j){o[d[j]]=o[d[j]]||{};o=o[d[j]];}}},urlEncode:function(o){if(!o){return "";}var buf=[];for(var key in o){var ov=o[key];var _2e=typeof ov;if(_2e=="undefined"){buf.push(encodeURIComponent(key),"=&");}else{if(_2e!="function"&&_2e!="object"){buf.push(encodeURIComponent(key),"=",encodeURIComponent(ov),"&");}else{if(ov instanceof Array){for(var i=0,len=ov.length;i<len;i++){buf.push(encodeURIComponent(key),"=",encodeURIComponent(ov[i]===undefined?"":ov[i]),"&");}}}}}buf.pop();return buf.join("");},urlDecode:function(_31,_32){if(!_31||!_31.length){return {};}var obj={};var _34=_31.split("&");var _35,_36,_37;for(var i=0,len=_34.length;i<len;i++){_35=_34[i].split("=");_36=_35[0];_37=_35[1];if(_32!==true){if(typeof obj[_36]=="undefined"){obj[_36]=_37;}else{if(typeof obj[_36]=="string"){obj[_36]=[obj[_36]];obj[_36].push(_37);}else{obj[_36].push(_37);}}}else{obj[_36]=_37;}}return obj;},each:function(_3a,fn,_3c){if(typeof _3a.length=="undefined"||typeof _3a=="string"){_3a=[_3a];}for(var i=0,len=_3a.length;i<len;i++){if(fn.call(_3c||_3a[i],_3a[i],i,_3a)===false){return i;}}},combine:function(){var as=arguments,l=as.length,r=[];for(var i=0;i<l;i++){var a=as[i];if(a instanceof Array){r=r.concat(a);}else{if(a.length!==undefined&&!a.substr){r=r.concat(Array.prototype.slice.call(a,0));}else{r.push(a);}}}return r;},escapeRe:function(s){return s.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1");},callback:function(cb,_46,_47,_48){if(typeof cb=="function"){if(_48){cb.defer(_48,_46,_47||[]);}else{cb.apply(_46,_47||[]);}}},getDom:function(el){if(!el){return null;}return el.dom?el.dom:(typeof el=="string"?document.getElementById(el):el);},num:function(v,_4b){if(typeof v!="number"){return _4b;}return v;},isOpera:_8,isSafari:_9,isIE:_a,isIE7:_b,isGecko:_c,isBorderBox:_d,isWindows:_e,isMac:_f,useShims:((_a&&!_b)||(_c&&_f))});})();Ext.namespace("Ext","Ext.util","Ext.grid","Ext.dd","Ext.tree","Ext.data","Ext.form","Ext.menu","Ext.state","Ext.lib");Ext.apply(Function.prototype,{createCallback:function(){var _4c=arguments;var _4d=this;return function(){return _4d.apply(window,_4c);};},createDelegate:function(obj,_4f,_50){var _51=this;return function(){var _52=_4f||arguments;if(_50===true){_52=Array.prototype.slice.call(arguments,0);_52=_52.concat(_4f);}else{if(typeof _50=="number"){_52=Array.prototype.slice.call(arguments,0);var _53=[_50,0].concat(_4f);Array.prototype.splice.apply(_52,_53);}}return _51.apply(obj||window,_52);};},defer:function(_54,obj,_56,_57){var fn=this.createDelegate(obj,_56,_57);if(_54){return setTimeout(fn,_54);}fn();return 0;},createSequence:function(fcn,_5a){if(typeof fcn!="function"){return this;}var _5b=this;return function(){var _5c=_5b.apply(this||window,arguments);fcn.apply(_5a||this||window,arguments);return _5c;};},createInterceptor:function(fcn,_5e){if(typeof fcn!="function"){return this;}var _5f=this;return function(){fcn.target=this;fcn.method=_5f;if(fcn.apply(_5e||this||window,arguments)===false){return;}return _5f.apply(this||window,arguments);};}});Ext.applyIf(String,{escape:function(_60){return _60.replace(/('|\\)/g,"\\$1");},leftPad:function(val,_62,ch){var _64=new String(val);if(ch==null){ch=" ";}while(_64.length<_62){_64=ch+_64;}return _64;},format:function(_65){var _66=Array.prototype.slice.call(arguments,1);return _65.replace(/\{(\d+)\}/g,function(m,i){return _66[i];});}});String.prototype.toggle=function(_69,_6a){return this==_69?_6a:_69;};Ext.applyIf(Number.prototype,{constrain:function(min,max){return Math.min(Math.max(this,min),max);}});Ext.applyIf(Array.prototype,{indexOf:function(o){for(var i=0,len=this.length;i<len;i++){if(this[i]==o){return i;}}return -1;},remove:function(o){var _71=this.indexOf(o);if(_71!=-1){this.splice(_71,1);}}});Date.prototype.getElapsed=function(_72){return Math.abs((_72||new Date()).getTime()-this.getTime());};
+
+if(typeof YAHOO=="undefined"){throw "Unable to load Ext, core YUI utilities (yahoo, dom, event) not found.";}(function(){var E=YAHOO.util.Event;var D=YAHOO.util.Dom;var CN=YAHOO.util.Connect;var ES=YAHOO.util.Easing;var A=YAHOO.util.Anim;var _6;Ext.lib.Dom={getViewWidth:function(_7){return _7?D.getDocumentWidth():D.getViewportWidth();},getViewHeight:function(_8){return _8?D.getDocumentHeight():D.getViewportHeight();},isAncestor:function(_9,_a){return D.isAncestor(_9,_a);},getRegion:function(el){return D.getRegion(el);},getY:function(el){return this.getXY(el)[1];},getX:function(el){return this.getXY(el)[0];},getXY:function(el){var p,pe,b,_12,bd=document.body;el=Ext.getDom(el);if(el.getBoundingClientRect){b=el.getBoundingClientRect();_12=fly(document).getScroll();return [b.left+_12.left,b.top+_12.top];}else{var x=el.offsetLeft,y=el.offsetTop;p=el.offsetParent;var _16=false;if(p!=el){while(p){x+=p.offsetLeft;y+=p.offsetTop;if(Ext.isSafari&&!_16&&fly(p).getStyle("position")=="absolute"){_16=true;}if(Ext.isGecko){pe=fly(p);var bt=parseInt(pe.getStyle("borderTopWidth"),10)||0;var bl=parseInt(pe.getStyle("borderLeftWidth"),10)||0;x+=bl;y+=bt;if(p!=el&&pe.getStyle("overflow")!="visible"){x+=bl;y+=bt;}}p=p.offsetParent;}}if(Ext.isSafari&&(_16||fly(el).getStyle("position")=="absolute")){x-=bd.offsetLeft;y-=bd.offsetTop;}}p=el.parentNode;while(p&&p!=bd){if(!Ext.isOpera||(Ext.isOpera&&p.tagName!="TR"&&fly(p).getStyle("display")!="inline")){x-=p.scrollLeft;y-=p.scrollTop;}p=p.parentNode;}return [x,y];},setXY:function(el,xy){el=Ext.fly(el,"_setXY");el.position();var pts=el.translatePoints(xy);if(xy[0]!==false){el.dom.style.left=pts.left+"px";}if(xy[1]!==false){el.dom.style.top=pts.top+"px";}},setX:function(el,x){this.setXY(el,[x,false]);},setY:function(el,y){this.setXY(el,[false,y]);}};Ext.lib.Event={getPageX:function(e){return E.getPageX(e.browserEvent||e);},getPageY:function(e){return E.getPageY(e.browserEvent||e);},getXY:function(e){return E.getXY(e.browserEvent||e);},getTarget:function(e){return E.getTarget(e.browserEvent||e);},getRelatedTarget:function(e){return E.getRelatedTarget(e.browserEvent||e);},on:function(el,_26,fn,_28,_29){E.on(el,_26,fn,_28,_29);},un:function(el,_2b,fn){E.removeListener(el,_2b,fn);},purgeElement:function(el){E.purgeElement(el);},preventDefault:function(e){E.preventDefault(e.browserEvent||e);},stopPropagation:function(e){E.stopPropagation(e.browserEvent||e);},stopEvent:function(e){E.stopEvent(e.browserEvent||e);},onAvailable:function(el,fn,_33,_34){return E.onAvailable(el,fn,_33,_34);}};Ext.lib.Ajax={request:function(_35,uri,cb,_38){return CN.asyncRequest(_35,uri,cb,_38);},formRequest:function(_39,uri,cb,_3c,_3d,_3e){CN.setForm(_39,_3d,_3e);return CN.asyncRequest("POST",uri,cb,_3c);},isCallInProgress:function(_3f){return CN.isCallInProgress(_3f);},abort:function(_40){return CN.abort(_40);},serializeForm:function(_41){var d=CN.setForm(_41.dom||_41);CN.resetFormState();return d;}};Ext.lib.Region=YAHOO.util.Region;Ext.lib.Point=YAHOO.util.Point;Ext.lib.Anim={scroll:function(el,_44,_45,_46,cb,_48){this.run(el,_44,_45,_46,cb,_48,YAHOO.util.Scroll);},motion:function(el,_4a,_4b,_4c,cb,_4e){this.run(el,_4a,_4b,_4c,cb,_4e,YAHOO.util.Motion);},color:function(el,_50,_51,_52,cb,_54){this.run(el,_50,_51,_52,cb,_54,YAHOO.util.ColorAnim);},run:function(el,_56,_57,_58,cb,_5a,_5b){_5b=_5b||YAHOO.util.Anim;if(typeof _58=="string"){_58=YAHOO.util.Easing[_58];}var _5c=new _5b(el,_56,_57,_58);_5c.animateX(function(){Ext.callback(cb,_5a);});return _5c;}};function fly(el){if(!_6){_6=new Ext.Element.Flyweight();}_6.dom=el;return _6;}if(Ext.isIE){YAHOO.util.Event.on(window,"unload",function(){var p=Function.prototype;delete p.createSequence;delete p.defer;delete p.createDelegate;delete p.createCallback;delete p.createInterceptor;});}if(YAHOO.util.Anim){YAHOO.util.Anim.prototype.animateX=function(_5f,_60){var f=function(){this.onComplete.unsubscribe(f);if(typeof _5f=="function"){_5f.call(_60||this,this);}};this.onComplete.subscribe(f,this,true);this.animate();};}if(YAHOO.util.DragDrop&&Ext.dd.DragDrop){YAHOO.util.DragDrop.defaultPadding=Ext.dd.DragDrop.defaultPadding;YAHOO.util.DragDrop.constrainTo=Ext.dd.DragDrop.constrainTo;}YAHOO.util.Dom.getXY=function(el){var f=function(el){return Ext.lib.Dom.getXY(el);};return YAHOO.util.Dom.batch(el,f,YAHOO.util.Dom,true);};if(YAHOO.util.AnimMgr){YAHOO.util.AnimMgr.fps=1000;}YAHOO.util.Region.prototype.adjust=function(t,l,b,r){this.top+=t;this.left+=l;this.right+=r;this.bottom+=b;return this;};})();
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/yui-utilities.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/adapter/yui/yui-utilities.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,18 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+if(typeof YAHOO=="undefined"){var YAHOO={};}YAHOO.namespace=function(){var a=arguments,o=null,i,j,d;for(i=0;i<a.length;i=i+1){d=a[i].split(".");o=YAHOO;for(j=(d[0]=="YAHOO")?1:0;j<d.length;j=j+1){o[d[j]]=o[d[j]]||{};o=o[d[j]];}}return o;};YAHOO.log=function(_6,_7,_8){var l=YAHOO.widget.Logger;if(l&&l.log){return l.log(_6,_7,_8);}else{return false;}};YAHOO.init=function(){this.namespace("util","widget","example");if(typeof YAHOO_config!="undefined"){var l=YAHOO_config.listener,ls=YAHOO.env.listeners,_c=true,i;if(l){for(i=0;i<ls.length;i=i+1){if(ls[i]==l){_c=false;break;}}if(_c){ls.push(l);}}}};YAHOO.register=function(_e,_f,_10){var _11=YAHOO.env.modules;if(!_11[_e]){_11[_e]={versions:[],builds:[]};}var m=_11[_e],v=_10.version,b=_10.build,ls=YAHOO.env.listeners;m.name=_e;m.version=v;m.build=b;m.versions.push(v);m.builds.push(b);m.mainClass=_f;for(var i=0;i<ls.length;i=i+1){ls[i](m);}if(_f){_f.VERSION=v;_f.BUILD=b;}else{YAHOO.log("mainClass is undefined for module "+_e,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[],getVersion:function(_17){return YAHOO.env.modules[_17]||null;}};YAHOO.lang={isArray:function(obj){if(obj.constructor&&obj.constructor.toString().indexOf("Array")>-1){return true;}else{return YAHOO.lang.isObject(obj)&&obj.constructor==Array;}},isBoolean:function(obj){return typeof obj=="boolean";},isFunction:function(obj){return typeof obj=="function";},isNull:function(obj){return obj===null;},isNumber:function(obj){return typeof obj=="number"&&isFinite(obj);},isObject:function(obj){return typeof obj=="object"||YAHOO.lang.isFunction(obj);},isString:function(obj){return typeof obj=="string";},isUndefined:function(obj){return typeof obj=="undefined";},hasOwnProperty:function(obj,_21){if(Object.prototype.hasOwnProperty){return obj.hasOwnProperty(_21);}return !YAHOO.lang.isUndefined(obj[_21])&&obj.constructor.prototype[_21]!==obj[_21];},extend:function(_22,_23,_24){var F=function(){};F.prototype=_23.prototype;_22.prototype=new F();_22.prototype.constructor=_22;_22.superclass=_23.prototype;if(_23.prototype.constructor==Object.prototype.constructor){_23.prototype.constructor=_23;}if(_24){for(var i in _24){_22.prototype[i]=_24[i];}}},augment:function(r,s){var rp=r.prototype,sp=s.prototype,a=arguments,i,p;if(a[2]){for(i=2;i<a.length;i=i+1){rp[a[i]]=sp[a[i]];}}else{for(p in sp){if(!rp[p]){rp[p]=sp[p];}}}}};YAHOO.init();YAHOO.util.Lang=YAHOO.lang;YAHOO.augment=YAHOO.lang.augment;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.2.0",build:"127"});
+
+(function(){var Y=YAHOO.util,_2,_3,_4=0,_5={};var ua=navigator.userAgent.toLowerCase(),_7=(ua.indexOf("opera")>-1),_8=(ua.indexOf("safari")>-1),_9=(!_7&&!_8&&ua.indexOf("gecko")>-1),_a=(!_7&&ua.indexOf("msie")>-1);var _b={HYPHEN:/(-[a-z])/i};var _c=function(_d){if(!_b.HYPHEN.test(_d)){return _d;}if(_5[_d]){return _5[_d];}while(_b.HYPHEN.exec(_d)){_d=_d.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}_5[_d]=_d;return _d;};if(document.defaultView&&document.defaultView.getComputedStyle){_2=function(el,_f){var _10=null;var _11=document.defaultView.getComputedStyle(el,"");if(_11){_10=_11[_c(_f)];}return el.style[_f]||_10;};}else{if(document.documentElement.currentStyle&&_a){_2=function(el,_13){switch(_c(_13)){case "opacity":var val=100;try{val=el.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(e){try{val=el.filters("alpha").opacity;}catch(e){}}return val/100;break;default:var _15=el.currentStyle?el.currentStyle[_13]:null;return (el.style[_13]||_15);}};}else{_2=function(el,_17){return el.style[_17];};}}if(_a){_3=function(el,_19,val){switch(_19){case "opacity":if(typeof el.style.filter=="string"){el.style.filter="alpha(opacity="+val*100+")";if(!el.currentStyle||!el.currentStyle.hasLayout){el.style.zoom=1;}}break;default:el.style[_19]=val;}};}else{_3=function(el,_1c,val){el.style[_1c]=val;};}YAHOO.util.Dom={get:function(el){if(!el){return null;}if(typeof el!="string"&&!(el instanceof Array)){return el;}if(typeof el=="string"){return document.getElementById(el);}else{var _1f=[];for(var i=0,len=el.length;i<len;++i){_1f[_1f.length]=Y.Dom.get(el[i]);}return _1f;}return null;},getStyle:function(el,_23){_23=_c(_23);var f=function(_25){return _2(_25,_23);};return Y.Dom.batch(el,f,Y.Dom,true);},setStyle:function(el,_27,val){_27=_c(_27);var f=function(_2a){_3(_2a,_27,val);};Y.Dom.batch(el,f,Y.Dom,true);},getXY:function(el){var f=function(el){if(el.parentNode===null||el.offsetParent===null||this.getStyle(el,"display")=="none"){return false;}var _2e=null;var pos=[];var box;if(el.getBoundingClientRect){box=el.getBoundingClientRect();var doc=document;if(!this.inDocument(el)&&parent.document!=document){doc=parent.document;if(!this.isAncestor(doc.documentElement,el)){return false;}}var _32=Math.max(doc.documentElement.scrollTop,doc.body.scrollTop);var _33=Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft);return [box.left+_33,box.top+_32];}else{pos=[el.offsetLeft,el.offsetTop];_2e=el.offsetParent;if(_2e!=el){while(_2e){pos[0]+=_2e.offsetLeft;pos[1]+=_2e.offsetTop;_2e=_2e.offsetParent;}}if(_8&&this.getStyle(el,"position")=="absolute"){pos[0]-=document.body.offsetLeft;pos[1]-=document.body.offsetTop;}}if(el.parentNode){_2e=el.parentNode;}else{_2e=null;}while(_2e&&_2e.tagName.toUpperCase()!="BODY"&&_2e.tagName.toUpperCase()!="HTML"){if(Y.Dom.getStyle(_2e,"display")!="inline"){pos[0]-=_2e.scrollLeft;pos[1]-=_2e.scrollTop;}if(_2e.parentNode){_2e=_2e.parentNode;}else{_2e=null;}}return pos;};return Y.Dom.batch(el,f,Y.Dom,true);},getX:function(el){var f=function(el){return Y.Dom.getXY(el)[0];};return Y.Dom.batch(el,f,Y.Dom,true);},getY:function(el){var f=function(el){return Y.Dom.getXY(el)[1];};return Y.Dom.batch(el,f,Y.Dom,true);},setXY:function(el,pos,_3c){var f=function(el){var _3f=this.getStyle(el,"position");if(_3f=="static"){this.setStyle(el,"position","relative");_3f="relative";}var _40=this.getXY(el);if(_40===false){return false;}var _41=[parseInt(this.getStyle(el,"left"),10),parseInt(this.getStyle(el,"top"),10)];if(isNaN(_41[0])){_41[0]=(_3f=="relative")?0:el.offsetLeft;}if(isNaN(_41[1])){_41[1]=(_3f=="relative")?0:el.offsetTop;}if(pos[0]!==null){el.style.left=pos[0]-_40[0]+_41[0]+"px";}if(pos[1]!==null){el.style.top=pos[1]-_40[1]+_41[1]+"px";}if(!_3c){var _42=this.getXY(el);if((pos[0]!==null&&_42[0]!=pos[0])||(pos[1]!==null&&_42[1]!=pos[1])){this.setXY(el,pos,true);}}};Y.Dom.batch(el,f,Y.Dom,true);},setX:function(el,x){Y.Dom.setXY(el,[x,null]);},setY:function(el,y){Y.Dom.setXY(el,[null,y]);},getRegion:function(el){var f=function(el){var _4a=new Y.Region.getRegion(el);return _4a;};return Y.Dom.batch(el,f,Y.Dom,true);},getClientWidth:function(){return Y.Dom.getViewportWidth();},getClientHeight:function(){return Y.Dom.getViewportHeight();},getElementsByClassName:function(_4b,tag,_4d){var _4e=function(el){return Y.Dom.hasClass(el,_4b);};return Y.Dom.getElementsBy(_4e,tag,_4d);},hasClass:function(el,_51){var re=new RegExp("(?:^|\\s+)"+_51+"(?:\\s+|$)");var f=function(el){return re.test(el["className"]);};return Y.Dom.batch(el,f,Y.Dom,true);},addClass:function(el,_56){var f=function(el){if(this.hasClass(el,_56)){return;}el["className"]=[el["className"],_56].join(" ");};Y.Dom.batch(el,f,Y.Dom,true);},removeClass:function(el,_5a){var re=new RegExp("(?:^|\\s+)"+_5a+"(?:\\s+|$)","g");var f=function(el){if(!this.hasClass(el,_5a)){return;}var c=el["className"];el["className"]=c.replace(re," ");if(this.hasClass(el,_5a)){this.removeClass(el,_5a);}};Y.Dom.batch(el,f,Y.Dom,true);},replaceClass:function(el,_60,_61){if(_60===_61){return false;}var re=new RegExp("(?:^|\\s+)"+_60+"(?:\\s+|$)","g");var f=function(el){if(!this.hasClass(el,_60)){this.addClass(el,_61);return;}el["className"]=el["className"].replace(re," "+_61+" ");if(this.hasClass(el,_60)){this.replaceClass(el,_60,_61);}};Y.Dom.batch(el,f,Y.Dom,true);},generateId:function(el,_66){_66=_66||"yui-gen";el=el||{};var f=function(el){if(el){el=Y.Dom.get(el);}else{el={};}if(!el.id){el.id=_66+_4++;}return el.id;};return Y.Dom.batch(el,f,Y.Dom,true);},isAncestor:function(_69,_6a){_69=Y.Dom.get(_69);if(!_69||!_6a){return false;}var f=function(_6c){if(_69.contains&&!_8){return _69.contains(_6c);}else{if(_69.compareDocumentPosition){return !!(_69.compareDocumentPosition(_6c)&16);}else{var _6d=_6c.parentNode;while(_6d){if(_6d==_69){return true;}else{if(!_6d.tagName||_6d.tagName.toUpperCase()=="HTML"){return false;}}_6d=_6d.parentNode;}return false;}}};return Y.Dom.batch(_6a,f,Y.Dom,true);},inDocument:function(el){var f=function(el){return this.isAncestor(document.documentElement,el);};return Y.Dom.batch(el,f,Y.Dom,true);},getElementsBy:function(_71,tag,_73){tag=tag||"*";var _74=[];if(_73){_73=Y.Dom.get(_73);if(!_73){return _74;}}else{_73=document;}var _75=_73.getElementsByTagName(tag);if(!_75.length&&(tag=="*"&&_73.all)){_75=_73.all;}for(var i=0,len=_75.length;i<len;++i){if(_71(_75[i])){_74[_74.length]=_75[i];}}return _74;},batch:function(el,_79,o,_7b){var id=el;el=Y.Dom.get(el);var _7d=(_7b)?o:window;if(!el||el.tagName||!el.length){if(!el){return false;}return _79.call(_7d,el,o);}var _7e=[];for(var i=0,len=el.length;i<len;++i){if(!el[i]){id=el[i];}_7e[_7e.length]=_79.call(_7d,el[i],o);}return _7e;},getDocumentHeight:function(){var _81=(document.compatMode!="CSS1Compat")?document.body.scrollHeight:document.documentElement.scrollHeight;var h=Math.max(_81,Y.Dom.getViewportHeight());return h;},getDocumentWidth:function(){var _83=(document.compatMode!="CSS1Compat")?document.body.scrollWidth:document.documentElement.scrollWidth;var w=Math.max(_83,Y.Dom.getViewportWidth());return w;},getViewportHeight:function(){var _85=self.innerHeight;var _86=document.compatMode;if((_86||_a)&&!_7){_85=(_86=="CSS1Compat")?document.documentElement.clientHeight:document.body.clientHeight;}return _85;},getViewportWidth:function(){var _87=self.innerWidth;var _88=document.compatMode;if(_88||_a){_87=(_88=="CSS1Compat")?document.documentElement.clientWidth:document.body.clientWidth;}return _87;}};})();YAHOO.util.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};YAHOO.util.Region.prototype.contains=function(_8d){return (_8d.left>=this.left&&_8d.right<=this.right&&_8d.top>=this.top&&_8d.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return ((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(_8e){var t=Math.max(this.top,_8e.top);var r=Math.min(this.right,_8e.right);var b=Math.min(this.bottom,_8e.bottom);var l=Math.max(this.left,_8e.left);if(b>=t&&r>=l){return new YAHOO.util.Region(t,r,b,l);}else{return null;}};YAHOO.util.Region.prototype.union=function(_93){var t=Math.min(this.top,_93.top);var r=Math.max(this.right,_93.right);var b=Math.max(this.bottom,_93.bottom);var l=Math.min(this.left,_93.left);return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Region.prototype.toString=function(){return ("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(el){var p=YAHOO.util.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];}this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.2.0",build:"127"});
+
+if(!YAHOO.util.Event){YAHOO.util.Event=function(){var _1=false;var _2=[];var _3=[];var _4=[];var _5=[];var _6=0;var _7=[];var _8=[];var _9=0;var _a=null;return {POLL_RETRYS:200,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,OBJ:3,ADJ_SCOPE:4,isSafari:(/KHTML/gi).test(navigator.userAgent),webkit:function(){var v=navigator.userAgent.match(/AppleWebKit\/([^ ]*)/);if(v&&v[1]){return v[1];}return null;}(),isIE:(!this.webkit&&!navigator.userAgent.match(/opera/gi)&&navigator.userAgent.match(/msie/gi)),_interval:null,startInterval:function(){if(!this._interval){var _c=this;var _d=function(){_c._tryPreloadAttach();};this._interval=setInterval(_d,this.POLL_INTERVAL);}},onAvailable:function(_e,_f,_10,_11){_7.push({id:_e,fn:_f,obj:_10,override:_11,checkReady:false});_6=this.POLL_RETRYS;this.startInterval();},onContentReady:function(_12,_13,_14,_15){_7.push({id:_12,fn:_13,obj:_14,override:_15,checkReady:true});_6=this.POLL_RETRYS;this.startInterval();},addListener:function(el,_17,fn,obj,_1a){if(!fn||!fn.call){return false;}if(this._isValidCollection(el)){var ok=true;for(var i=0,len=el.length;i<len;++i){ok=this.on(el[i],_17,fn,obj,_1a)&&ok;}return ok;}else{if(typeof el=="string"){var oEl=this.getEl(el);if(oEl){el=oEl;}else{this.onAvailable(el,function(){YAHOO.util.Event.on(el,_17,fn,obj,_1a);});return true;}}}if(!el){return false;}if("unload"==_17&&obj!==this){_3[_3.length]=[el,_17,fn,obj,_1a];return true;}var _1f=el;if(_1a){if(_1a===true){_1f=obj;}else{_1f=_1a;}}var _20=function(e){return fn.call(_1f,YAHOO.util.Event.getEvent(e),obj);};var li=[el,_17,fn,_20,_1f];var _23=_2.length;_2[_23]=li;if(this.useLegacyEvent(el,_17)){var _24=this.getLegacyIndex(el,_17);if(_24==-1||el!=_4[_24][0]){_24=_4.length;_8[el.id+_17]=_24;_4[_24]=[el,_17,el["on"+_17]];_5[_24]=[];el["on"+_17]=function(e){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(e),_24);};}_5[_24].push(li);}else{try{this._simpleAdd(el,_17,_20,false);}catch(ex){this.lastError=ex;this.removeListener(el,_17,fn);return false;}}return true;},fireLegacyEvent:function(e,_27){var ok=true,le,lh,li,_2c,ret;lh=_5[_27];for(var i=0,len=lh.length;i<len;++i){li=lh[i];if(li&&li[this.WFN]){_2c=li[this.ADJ_SCOPE];ret=li[this.WFN].call(_2c,e);ok=(ok&&ret);}}le=_4[_27];if(le&&le[2]){le[2](e);}return ok;},getLegacyIndex:function(el,_31){var key=this.generateId(el)+_31;if(typeof _8[key]=="undefined"){return -1;}else{return _8[key];}},useLegacyEvent:function(el,_34){if(this.webkit&&("click"==_34||"dblclick"==_34)){var v=parseInt(this.webkit,10);if(!isNaN(v)&&v<418){return true;}}return false;},removeListener:function(el,_37,fn){var i,len;if(typeof el=="string"){el=this.getEl(el);}else{if(this._isValidCollection(el)){var ok=true;for(i=0,len=el.length;i<len;++i){ok=(this.removeListener(el[i],_37,fn)&&ok);}return ok;}}if(!fn||!fn.call){return this.purgeElement(el,false,_37);}if("unload"==_37){for(i=0,len=_3.length;i<len;i++){var li=_3[i];if(li&&li[0]==el&&li[1]==_37&&li[2]==fn){_3.splice(i,1);return true;}}return false;}var _3d=null;var _3e=arguments[3];if("undefined"==typeof _3e){_3e=this._getCacheIndex(el,_37,fn);}if(_3e>=0){_3d=_2[_3e];}if(!el||!_3d){return false;}if(this.useLegacyEvent(el,_37)){var _3f=this.getLegacyIndex(el,_37);var _40=_5[_3f];if(_40){for(i=0,len=_40.length;i<len;++i){li=_40[i];if(li&&li[this.EL]==el&&li[this.TYPE]==_37&&li[this.FN]==fn){_40.splice(i,1);break;}}}}else{try{this._simpleRemove(el,_37,_3d[this.WFN],false);}catch(ex){this.lastError=ex;return false;}}delete _2[_3e][this.WFN];delete _2[_3e][this.FN];_2.splice(_3e,1);return true;},getTarget:function(ev,_42){var t=ev.target||ev.srcElement;return this.resolveTextNode(t);},resolveTextNode:function(_44){if(_44&&3==_44.nodeType){return _44.parentNode;}else{return _44;}},getPageX:function(ev){var x=ev.pageX;if(!x&&0!==x){x=ev.clientX||0;if(this.isIE){x+=this._getScrollLeft();}}return x;},getPageY:function(ev){var y=ev.pageY;if(!y&&0!==y){y=ev.clientY||0;if(this.isIE){y+=this._getScrollTop();}}return y;},getXY:function(ev){return [this.getPageX(ev),this.getPageY(ev)];},getRelatedTarget:function(ev){var t=ev.relatedTarget;if(!t){if(ev.type=="mouseout"){t=ev.toElement;}else{if(ev.type=="mouseover"){t=ev.fromElement;}}}return this.resolveTextNode(t);},getTime:function(ev){if(!ev.time){var t=new Date().getTime();try{ev.time=t;}catch(ex){this.lastError=ex;return t;}}return ev.time;},stopEvent:function(ev){this.stopPropagation(ev);this.preventDefault(ev);},stopPropagation:function(ev){if(ev.stopPropagation){ev.stopPropagation();}else{ev.cancelBubble=true;}},preventDefault:function(ev){if(ev.preventDefault){ev.preventDefault();}else{ev.returnValue=false;}},getEvent:function(e){var ev=e||window.event;if(!ev){var c=this.getEvent.caller;while(c){ev=c.arguments[0];if(ev&&Event==ev.constructor){break;}c=c.caller;}}return ev;},getCharCode:function(ev){return ev.charCode||ev.keyCode||0;},_getCacheIndex:function(el,_56,fn){for(var i=0,len=_2.length;i<len;++i){var li=_2[i];if(li&&li[this.FN]==fn&&li[this.EL]==el&&li[this.TYPE]==_56){return i;}}return -1;},generateId:function(el){var id=el.id;if(!id){id="yuievtautoid-"+_9;++_9;el.id=id;}return id;},_isValidCollection:function(o){return (o&&o.length&&typeof o!="string"&&!o.tagName&&!o.alert&&typeof o[0]!="undefined");},elCache:{},getEl:function(id){return document.getElementById(id);},clearCache:function(){},_load:function(e){_1=true;var EU=YAHOO.util.Event;if(this.isIE){EU._simpleRemove(window,"load",EU._load);}},_tryPreloadAttach:function(){if(this.locked){return false;}this.locked=true;var _61=!_1;if(!_61){_61=(_6>0);}var _62=[];for(var i=0,len=_7.length;i<len;++i){var _65=_7[i];if(_65){var el=this.getEl(_65.id);if(el){if(!_65.checkReady||_1||el.nextSibling||(document&&document.body)){var _67=el;if(_65.override){if(_65.override===true){_67=_65.obj;}else{_67=_65.override;}}_65.fn.call(_67,_65.obj);_7[i]=null;}}else{_62.push(_65);}}}_6=(_62.length===0)?0:_6-1;if(_61){this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;return true;},purgeElement:function(el,_69,_6a){var _6b=this.getListeners(el,_6a);if(_6b){for(var i=0,len=_6b.length;i<len;++i){var l=_6b[i];this.removeListener(el,l.type,l.fn);}}if(_69&&el&&el.childNodes){for(i=0,len=el.childNodes.length;i<len;++i){this.purgeElement(el.childNodes[i],_69,_6a);}}},getListeners:function(el,_70){var _71=[],_72;if(!_70){_72=[_2,_3];}else{if(_70=="unload"){_72=[_3];}else{_72=[_2];}}for(var j=0;j<_72.length;++j){var _74=_72[j];if(_74&&_74.length>0){for(var i=0,len=_74.length;i<len;++i){var l=_74[i];if(l&&l[this.EL]===el&&(!_70||_70===l[this.TYPE])){_71.push({type:l[this.TYPE],fn:l[this.FN],obj:l[this.OBJ],adjust:l[this.ADJ_SCOPE],index:i});}}}}return (_71.length)?_71:null;},_unload:function(e){var EU=YAHOO.util.Event,i,j,l,len,_7e;for(i=0,len=_3.length;i<len;++i){l=_3[i];if(l){var _7f=window;if(l[EU.ADJ_SCOPE]){if(l[EU.ADJ_SCOPE]===true){_7f=l[EU.OBJ];}else{_7f=l[EU.ADJ_SCOPE];}}l[EU.FN].call(_7f,EU.getEvent(e),l[EU.OBJ]);_3[i]=null;l=null;_7f=null;}}_3=null;if(_2&&_2.length>0){j=_2.length;while(j){_7e=j-1;l=_2[_7e];if(l){EU.removeListener(l[EU.EL],l[EU.TYPE],l[EU.FN],_7e);}j=j-1;}l=null;EU.clearCache();}for(i=0,len=_4.length;i<len;++i){_4[i][0]=null;_4[i]=null;}_4=null;EU._simpleRemove(window,"unload",EU._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var dd=document.documentElement,db=document.body;if(dd&&(dd.scrollTop||dd.scrollLeft)){return [dd.scrollTop,dd.scrollLeft];}else{if(db){return [db.scrollTop,db.scrollLeft];}else{return [0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(el,_83,fn,_85){el.addEventListener(_83,fn,(_85));};}else{if(window.attachEvent){return function(el,_87,fn,_89){el.attachEvent("on"+_87,fn);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(el,_8b,fn,_8d){el.removeEventListener(_8b,fn,(_8d));};}else{if(window.detachEvent){return function(el,_8f,fn){el.detachEvent("on"+_8f,fn);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;if(document&&document.body){EU._load();}else{EU._simpleAdd(window,"load",EU._load);}EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.CustomEvent=function(_92,_93,_94,_95){this.type=_92;this.scope=_93||window;this.silent=_94;this.signature=_95||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var _96="_YUICEOnSubscribe";if(_92!==_96){this.subscribeEvent=new YAHOO.util.CustomEvent(_96,this,true);}};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(fn,obj,_99){if(this.subscribeEvent){this.subscribeEvent.fire(fn,obj,_99);}this.subscribers.push(new YAHOO.util.Subscriber(fn,obj,_99));},unsubscribe:function(fn,obj){if(!fn){return this.unsubscribeAll();}var _9c=false;for(var i=0,len=this.subscribers.length;i<len;++i){var s=this.subscribers[i];if(s&&s.contains(fn,obj)){this._delete(i);_9c=true;}}return _9c;},fire:function(){var len=this.subscribers.length;if(!len&&this.silent){return true;}var _a1=[],ret=true,i;for(i=0;i<arguments.length;++i){_a1.push(arguments[i]);}var _a4=_a1.length;if(!this.silent){}for(i=0;i<len;++i){var s=this.subscribers[i];if(s){if(!this.silent){}var _a6=s.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var _a7=null;if(_a1.length>0){_a7=_a1[0];}ret=s.fn.call(_a6,_a7,s.obj);}else{ret=s.fn.call(_a6,this.type,_a1,s.obj);}if(false===ret){if(!this.silent){}return false;}}}return true;},unsubscribeAll:function(){for(var i=0,len=this.subscribers.length;i<len;++i){this._delete(len-1-i);}return i;},_delete:function(_aa){var s=this.subscribers[_aa];if(s){delete s.fn;delete s.obj;}this.subscribers.splice(_aa,1);},toString:function(){return "CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(fn,obj,_ae){this.fn=fn;this.obj=obj||null;this.override=_ae;};YAHOO.util.Subscriber.prototype.getScope=function(_af){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return _af;};YAHOO.util.Subscriber.prototype.contains=function(fn,obj){if(obj){return (this.fn==fn&&this.obj==obj);}else{return (this.fn==fn);}};YAHOO.util.Subscriber.prototype.toString=function(){return "Subscriber { obj: "+(this.obj||"")+", override: "+(this.override||"no")+" }";};YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(_b2,_b3,_b4,_b5){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[_b2];if(ce){ce.subscribe(_b3,_b4,_b5);}else{this.__yui_subscribers=this.__yui_subscribers||{};var _b7=this.__yui_subscribers;if(!_b7[_b2]){_b7[_b2]=[];}_b7[_b2].push({fn:_b3,obj:_b4,override:_b5});}},unsubscribe:function(_b8,_b9,_ba){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[_b8];if(ce){return ce.unsubscribe(_b9,_ba);}else{return false;}},unsubscribeAll:function(_bc){return this.unsubscribe(_bc);},createEvent:function(_bd,_be){this.__yui_events=this.__yui_events||{};var _bf=_be||{};var _c0=this.__yui_events;if(_c0[_bd]){}else{var _c1=_bf.scope||this;var _c2=_bf.silent||null;var ce=new YAHOO.util.CustomEvent(_bd,_c1,_c2,YAHOO.util.CustomEvent.FLAT);_c0[_bd]=ce;if(_bf.onSubscribeCallback){ce.subscribeEvent.subscribe(_bf.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var qs=this.__yui_subscribers[_bd];if(qs){for(var i=0;i<qs.length;++i){ce.subscribe(qs[i].fn,qs[i].obj,qs[i].override);}}}return _c0[_bd];},fireEvent:function(_c6,_c7,_c8,etc){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[_c6];if(ce){var _cb=[];for(var i=1;i<arguments.length;++i){_cb.push(arguments[i]);}return ce.fire.apply(ce,_cb);}else{return null;}},hasEvent:function(_cd){if(this.__yui_events){if(this.__yui_events[_cd]){return true;}}return false;}};YAHOO.util.KeyListener=function(_ce,_cf,_d0,_d1){if(!_ce){}else{if(!_cf){}else{if(!_d0){}}}if(!_d1){_d1=YAHOO.util.KeyListener.KEYDOWN;}var _d2=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof _ce=="string"){_ce=document.getElementById(_ce);}if(typeof _d0=="function"){_d2.subscribe(_d0);}else{_d2.subscribe(_d0.fn,_d0.scope,_d0.correctScope);}function handleKeyPress(e,obj){if(!_cf.shift){_cf.shift=false;}if(!_cf.alt){_cf.alt=false;}if(!_cf.ctrl){_cf.ctrl=false;}if(e.shiftKey==_cf.shift&&e.altKey==_cf.alt&&e.ctrlKey==_cf.ctrl){var _d5;var _d6;if(_cf.keys instanceof Array){for(var i=0;i<_cf.keys.length;i++){_d5=_cf.keys[i];if(_d5==e.charCode){_d2.fire(e.charCode,e);break;}else{if(_d5==e.keyCode){_d2.fire(e.keyCode,e);break;}}}}else{_d5=_cf.keys;if(_d5==e.charCode){_d2.fire(e.charCode,e);}else{if(_d5==e.keyCode){_d2.fire(e.keyCode,e);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(_ce,_d1,handleKeyPress);this.enabledEvent.fire(_cf);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(_ce,_d1,handleKeyPress);this.disabledEvent.fire(_cf);}this.enabled=false;};this.toString=function(){return "KeyListener ["+_cf.keys+"] "+_ce.tagName+(_ce.id?"["+_ce.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.register("event",YAHOO.util.Event,{version:"2.2.0",build:"127"});
+
+YAHOO.util.Connect={_msxml_progid:["MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:"application/x-www-form-urlencoded",_use_default_xhr_header:true,_default_xhr_header:"XMLHttpRequest",_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,setProgId:function(id){this._msxml_progid.unshift(id);},setDefaultPostHeader:function(b){this._use_default_post_header=b;},setDefaultXhrHeader:function(b){this._use_default_xhr_header=b;},setPollingInterval:function(i){if(typeof i=="number"&&isFinite(i)){this._polling_interval=i;}},createXhrObject:function(_5){var _6,_7;try{_7=new XMLHttpRequest();_6={conn:_7,tId:_5};}catch(e){for(var i=0;i<this._msxml_progid.length;++i){try{_7=new ActiveXObject(this._msxml_progid[i]);_6={conn:_7,tId:_5};break;}catch(e){}}}finally{return _6;}},getConnectionObject:function(){var o;var _a=this._transaction_id;try{o=this.createXhrObject(_a);if(o){this._transaction_id++;}}catch(e){}finally{return o;}},asyncRequest:function(_b,_c,_d,_e){var o=this.getConnectionObject();if(!o){return null;}else{if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(o.tId,_d,_c,_e);this.releaseObject(o);return;}if(_b.toUpperCase()=="GET"){if(this._sFormData.length!=0){_c+=((_c.indexOf("?")==-1)?"?":"&")+this._sFormData;}else{_c+="?"+this._sFormData;}}else{if(_b.toUpperCase()=="POST"){_e=_e?this._sFormData+"&"+_e:this._sFormData;}}}o.conn.open(_b,_c,true);if(this._use_default_xhr_header){if(!this._default_headers["X-Requested-With"]){this.initHeader("X-Requested-With",this._default_xhr_header,true);}}if(this._isFormSubmit||(_e&&this._use_default_post_header)){this.initHeader("Content-Type",this._default_post_header);if(this._isFormSubmit){this.resetFormState();}}if(this._has_default_headers||this._has_http_headers){this.setHeader(o);}this.handleReadyState(o,_d);o.conn.send(_e||null);return o;}},handleReadyState:function(o,_11){var _12=this;if(_11&&_11.timeout){this._timeOut[o.tId]=window.setTimeout(function(){_12.abort(o,_11,true);},_11.timeout);}this._poll[o.tId]=window.setInterval(function(){if(o.conn&&o.conn.readyState==4){window.clearInterval(_12._poll[o.tId]);delete _12._poll[o.tId];if(_11&&_11.timeout){delete _12._timeOut[o.tId];}_12.handleTransactionResponse(o,_11);}},this._polling_interval);},handleTransactionResponse:function(o,_14,_15){if(!_14){this.releaseObject(o);return;}var _16,_17;try{if(o.conn.status!==undefined&&o.conn.status!=0){_16=o.conn.status;}else{_16=13030;}}catch(e){_16=13030;}if(_16>=200&&_16<300){_17=this.createResponseObject(o,_14.argument);if(_14.success){if(!_14.scope){_14.success(_17);}else{_14.success.apply(_14.scope,[_17]);}}}else{switch(_16){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:_17=this.createExceptionObject(o.tId,_14.argument,(_15?_15:false));if(_14.failure){if(!_14.scope){_14.failure(_17);}else{_14.failure.apply(_14.scope,[_17]);}}break;default:_17=this.createResponseObject(o,_14.argument);if(_14.failure){if(!_14.scope){_14.failure(_17);}else{_14.failure.apply(_14.scope,[_17]);}}}}this.releaseObject(o);_17=null;},createResponseObject:function(o,_19){var obj={};var _1b={};try{var _1c=o.conn.getAllResponseHeaders();var _1d=_1c.split("\n");for(var i=0;i<_1d.length;i++){var _1f=_1d[i].indexOf(":");if(_1f!=-1){_1b[_1d[i].substring(0,_1f)]=_1d[i].substring(_1f+2);}}}catch(e){}obj.tId=o.tId;obj.status=o.conn.status;obj.statusText=o.conn.statusText;obj.getResponseHeader=_1b;obj.getAllResponseHeaders=_1c;obj.responseText=o.conn.responseText;obj.responseXML=o.conn.responseXML;if(typeof _19!==undefined){obj.argument=_19;}return obj;},createExceptionObject:function(tId,_21,_22){var _23=0;var _24="communication failure";var _25=-1;var _26="transaction aborted";var obj={};obj.tId=tId;if(_22){obj.status=_25;obj.statusText=_26;}else{obj.status=_23;obj.statusText=_24;}if(_21){obj.argument=_21;}return obj;},initHeader:function(_28,_29,_2a){var _2b=(_2a)?this._default_headers:this._http_headers;if(_2b[_28]===undefined){_2b[_28]=_29;}else{_2b[_28]=_29+","+_2b[_28];}if(_2a){this._has_default_headers=true;}else{this._has_http_headers=true;}},setHeader:function(o){if(this._has_default_headers){for(var _2d in this._default_headers){if(YAHOO.lang.hasOwnProperty(this._default_headers,_2d)){o.conn.setRequestHeader(_2d,this._default_headers[_2d]);}}}if(this._has_http_headers){for(var _2d in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,_2d)){o.conn.setRequestHeader(_2d,this._http_headers[_2d]);}}delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers;this._default_headers={};this._has_default_headers=false;},setForm:function(_2e,_2f,_30){this.resetFormState();var _31;if(typeof _2e=="string"){_31=(document.getElementById(_2e)||document.forms[_2e]);}else{if(typeof _2e=="object"){_31=_2e;}else{return;}}if(_2f){this.createFrame(_30?_30:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=_31;return;}var _32,_33,_34,_35;var _36=false;for(var i=0;i<_31.elements.length;i++){_32=_31.elements[i];_35=_31.elements[i].disabled;_33=_31.elements[i].name;_34=_31.elements[i].value;if(!_35&&_33){switch(_32.type){case "select-one":case "select-multiple":for(var j=0;j<_32.options.length;j++){if(_32.options[j].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(_33)+"="+encodeURIComponent(_32.options[j].attributes["value"].specified?_32.options[j].value:_32.options[j].text)+"&";}else{this._sFormData+=encodeURIComponent(_33)+"="+encodeURIComponent(_32.options[j].hasAttribute("value")?_32.options[j].value:_32.options[j].text)+"&";}}}break;case "radio":case "checkbox":if(_32.checked){this._sFormData+=encodeURIComponent(_33)+"="+encodeURIComponent(_34)+"&";}break;case "file":case undefined:case "reset":case "button":break;case "submit":if(_36==false){this._sFormData+=encodeURIComponent(_33)+"="+encodeURIComponent(_34)+"&";_36=true;}break;default:this._sFormData+=encodeURIComponent(_33)+"="+encodeURIComponent(_34)+"&";break;}}}this._isFormSubmit=true;this._sFormData=this._sFormData.substr(0,this._sFormData.length-1);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},createFrame:function(_39){var _3a="yuiIO"+this._transaction_id;if(window.ActiveXObject){var io=document.createElement("<iframe id=\""+_3a+"\" name=\""+_3a+"\" />");if(typeof _39=="boolean"){io.src="javascript:false";}else{if(typeof secureURI=="string"){io.src=_39;}}}else{var io=document.createElement("iframe");io.id=_3a;io.name=_3a;}io.style.position="absolute";io.style.top="-1000px";io.style.left="-1000px";document.body.appendChild(io);},appendPostData:function(_3c){var _3d=[];var _3e=_3c.split("&");for(var i=0;i<_3e.length;i++){var _40=_3e[i].indexOf("=");if(_40!=-1){_3d[i]=document.createElement("input");_3d[i].type="hidden";_3d[i].name=_3e[i].substring(0,_40);_3d[i].value=_3e[i].substring(_40+1);this._formNode.appendChild(_3d[i]);}}return _3d;},uploadFile:function(id,_42,uri,_44){var _45="yuiIO"+id;var _46="multipart/form-data";var io=document.getElementById(_45);this._formNode.action=uri;this._formNode.method="POST";this._formNode.target=_45;if(this._formNode.encoding){this._formNode.encoding=_46;}else{this._formNode.enctype=_46;}if(_44){var _48=this.appendPostData(_44);}this._formNode.submit();if(_48&&_48.length>0){for(var i=0;i<_48.length;i++){this._formNode.removeChild(_48[i]);}}this.resetFormState();var _4a=function(){var obj={};obj.tId=id;obj.argument=_42.argument;try{obj.responseText=io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;obj.responseXML=io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;}catch(e){}if(_42&&_42.upload){if(!_42.scope){_42.upload(obj);}else{_42.upload.apply(_42.scope,[obj]);}}if(YAHOO.util.Event){YAHOO.util.Event.removeListener(io,"load",_4a);}else{if(window.detachEvent){io.detachEvent("onload",_4a);}else{io.removeEventListener("load",_4a,false);}}setTimeout(function(){document.body.removeChild(io);},100);};if(YAHOO.util.Event){YAHOO.util.Event.addListener(io,"load",_4a);}else{if(window.attachEvent){io.attachEvent("onload",_4a);}else{io.addEventListener("load",_4a,false);}}},abort:function(o,_4d,_4e){if(this.isCallInProgress(o)){o.conn.abort();window.clearInterval(this._poll[o.tId]);delete this._poll[o.tId];if(_4e){delete this._timeOut[o.tId];}this.handleTransactionResponse(o,_4d,true);return true;}else{return false;}},isCallInProgress:function(o){if(o.conn){return o.conn.readyState!=4&&o.conn.readyState!=0;}else{return false;}},releaseObject:function(o){o.conn=null;o=null;}};YAHOO.register("connection",YAHOO.widget.Module,{version:"2.2.0",build:"127"});
+
+YAHOO.util.Anim=function(el,_2,_3,_4){if(el){this.init(el,_2,_3,_4);}};YAHOO.util.Anim.prototype={toString:function(){var el=this.getEl();var id=el.id||el.tagName;return ("Anim "+id);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(_7,_8,_9){return this.method(this.currentFrame,_8,_9-_8,this.totalFrames);},setAttribute:function(_a,_b,_c){if(this.patterns.noNegatives.test(_a)){_b=(_b>0)?_b:0;}YAHOO.util.Dom.setStyle(this.getEl(),_a,_b+_c);},getAttribute:function(_d){var el=this.getEl();var _f=YAHOO.util.Dom.getStyle(el,_d);if(_f!=="auto"&&!this.patterns.offsetUnit.test(_f)){return parseFloat(_f);}var a=this.patterns.offsetAttribute.exec(_d)||[];var pos=!!(a[3]);var box=!!(a[2]);if(box||(YAHOO.util.Dom.getStyle(el,"position")=="absolute"&&pos)){_f=el["offset"+a[0].charAt(0).toUpperCase()+a[0].substr(1)];}else{_f=0;}return _f;},getDefaultUnit:function(_13){if(this.patterns.defaultUnit.test(_13)){return "px";}return "";},setRuntimeAttribute:function(_14){var _15;var end;var _17=this.attributes;this.runtimeAttributes[_14]={};var _18=function(_19){return (typeof _19!=="undefined");};if(!_18(_17[_14]["to"])&&!_18(_17[_14]["by"])){return false;}_15=(_18(_17[_14]["from"]))?_17[_14]["from"]:this.getAttribute(_14);if(_18(_17[_14]["to"])){end=_17[_14]["to"];}else{if(_18(_17[_14]["by"])){if(_15.constructor==Array){end=[];for(var i=0,len=_15.length;i<len;++i){end[i]=_15[i]+_17[_14]["by"][i];}}else{end=_15+_17[_14]["by"];}}}this.runtimeAttributes[_14].start=_15;this.runtimeAttributes[_14].end=end;this.runtimeAttributes[_14].unit=(_18(_17[_14].unit))?_17[_14]["unit"]:this.getDefaultUnit(_14);},init:function(el,_1d,_1e,_1f){var _20=false;var _21=null;var _22=0;el=YAHOO.util.Dom.get(el);this.attributes=_1d||{};this.duration=_1e||1;this.method=_1f||YAHOO.util.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=YAHOO.util.AnimMgr.fps;this.getEl=function(){return el;};this.isAnimated=function(){return _20;};this.getStartTime=function(){return _21;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(YAHOO.util.AnimMgr.fps*this.duration):this.duration;YAHOO.util.AnimMgr.registerElement(this);};this.stop=function(_23){if(_23){this.currentFrame=this.totalFrames;this._onTween.fire();}YAHOO.util.AnimMgr.stop(this);};var _24=function(){this.onStart.fire();this.runtimeAttributes={};for(var _25 in this.attributes){this.setRuntimeAttribute(_25);}_20=true;_22=0;_21=new Date();};var _26=function(){var _27={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};_27.toString=function(){return ("duration: "+_27.duration+", currentFrame: "+_27.currentFrame);};this.onTween.fire(_27);var _28=this.runtimeAttributes;for(var _29 in _28){this.setAttribute(_29,this.doMethod(_29,_28[_29].start,_28[_29].end),_28[_29].unit);}_22+=1;};var _2a=function(){var _2b=(new Date()-_21)/1000;var _2c={duration:_2b,frames:_22,fps:_22/_2b};_2c.toString=function(){return ("duration: "+_2c.duration+", frames: "+_2c.frames+", fps: "+_2c.fps);};_20=false;_22=0;this.onComplete.fire(_2c);};this._onStart=new YAHOO.util.CustomEvent("_start",this,true);this.onStart=new YAHOO.util.CustomEvent("start",this);this.onTween=new YAHOO.util.CustomEvent("tween",this);this._onTween=new YAHOO.util.CustomEvent("_tween",this,true);this.onComplete=new YAHOO.util.CustomEvent("complete",this);this._onComplete=new YAHOO.util.CustomEvent("_complete",this,true);this._onStart.subscribe(_24);this._onTween.subscribe(_26);this._onComplete.subscribe(_2a);}};YAHOO.util.AnimMgr=new function(){var _2d=null;var _2e=[];var _2f=0;this.fps=1000;this.delay=1;this.registerElement=function(_30){_2e[_2e.length]=_30;_2f+=1;_30._onStart.fire();this.start();};this.unRegister=function(_31,_32){_31._onComplete.fire();_32=_32||_33(_31);if(_32!=-1){_2e.splice(_32,1);}_2f-=1;if(_2f<=0){this.stop();}};this.start=function(){if(_2d===null){_2d=setInterval(this.run,this.delay);}};this.stop=function(_34){if(!_34){clearInterval(_2d);for(var i=0,len=_2e.length;i<len;++i){if(_2e[0].isAnimated()){this.unRegister(_2e[0],0);}}_2e=[];_2d=null;_2f=0;}else{this.unRegister(_34);}};this.run=function(){for(var i=0,len=_2e.length;i<len;++i){var _39=_2e[i];if(!_39||!_39.isAnimated()){continue;}if(_39.currentFrame<_39.totalFrames||_39.totalFrames===null){_39.currentFrame+=1;if(_39.useSeconds){_3a(_39);}_39._onTween.fire();}else{YAHOO.util.AnimMgr.stop(_39,i);}}};var _33=function(_3b){for(var i=0,len=_2e.length;i<len;++i){if(_2e[i]==_3b){return i;}}return -1;};var _3a=function(_3e){var _3f=_3e.totalFrames;var _40=_3e.currentFrame;var _41=(_3e.currentFrame*_3e.duration*1000/_3e.totalFrames);var _42=(new Date()-_3e.getStartTime());var _43=0;if(_42<_3e.duration*1000){_43=Math.round((_42/_41-1)*_3e.currentFrame);}else{_43=_3f-(_40+1);}if(_43>0&&isFinite(_43)){if(_3e.currentFrame+_43>=_3f){_43=_3f-(_40+1);}_3e.currentFrame+=_43;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(_44,t){var n=_44.length;var tmp=[];for(var i=0;i<n;++i){tmp[i]=[_44[i][0],_44[i][1]];}for(var j=1;j<n;++j){for(i=0;i<n-j;++i){tmp[i][0]=(1-t)*tmp[i][0]+t*tmp[parseInt(i+1,10)][0];tmp[i][1]=(1-t)*tmp[i][1]+t*tmp[parseInt(i+1,10)][1];}}return [tmp[0][0],tmp[0][1]];};};(function(){YAHOO.util.ColorAnim=function(el,_4b,_4c,_4d){YAHOO.util.ColorAnim.superclass.constructor.call(this,el,_4b,_4c,_4d);};YAHOO.extend(YAHOO.util.ColorAnim,YAHOO.util.Anim);var Y=YAHOO.util;var _4f=Y.ColorAnim.superclass;var _50=Y.ColorAnim.prototype;_50.toString=function(){var el=this.getEl();var id=el.id||el.tagName;return ("ColorAnim "+id);};_50.patterns.color=/color$/i;_50.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;_50.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;_50.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;_50.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;_50.parseColor=function(s){if(s.length==3){return s;}var c=this.patterns.hex.exec(s);if(c&&c.length==4){return [parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];}c=this.patterns.rgb.exec(s);if(c&&c.length==4){return [parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];}c=this.patterns.hex3.exec(s);if(c&&c.length==4){return [parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];}return null;};_50.getAttribute=function(_55){var el=this.getEl();if(this.patterns.color.test(_55)){var val=YAHOO.util.Dom.getStyle(el,_55);if(this.patterns.transparent.test(val)){var _58=el.parentNode;val=Y.Dom.getStyle(_58,_55);while(_58&&this.patterns.transparent.test(val)){_58=_58.parentNode;val=Y.Dom.getStyle(_58,_55);if(_58.tagName.toUpperCase()=="HTML"){val="#fff";}}}}else{val=_4f.getAttribute.call(this,_55);}return val;};_50.doMethod=function(_59,_5a,end){var val;if(this.patterns.color.test(_59)){val=[];for(var i=0,len=_5a.length;i<len;++i){val[i]=_4f.doMethod.call(this,_59,_5a[i],end[i]);}val="rgb("+Math.floor(val[0])+","+Math.floor(val[1])+","+Math.floor(val[2])+")";}else{val=_4f.doMethod.call(this,_59,_5a,end);}return val;};_50.setRuntimeAttribute=function(_5f){_4f.setRuntimeAttribute.call(this,_5f);if(this.patterns.color.test(_5f)){var _60=this.attributes;var _61=this.parseColor(this.runtimeAttributes[_5f].start);var end=this.parseColor(this.runtimeAttributes[_5f].end);if(typeof _60[_5f]["to"]==="undefined"&&typeof _60[_5f]["by"]!=="undefined"){end=this.parseColor(_60[_5f].by);for(var i=0,len=_61.length;i<len;++i){end[i]=_61[i]+end[i];}}this.runtimeAttributes[_5f].start=_61;this.runtimeAttributes[_5f].end=end;}};})();YAHOO.util.Easing={easeNone:function(t,b,c,d){return c*t/d+b;},easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return -c*(t/=d)*(t-2)+b;},easeBoth:function(t,b,c,d){if((t/=d/2)<1){return c/2*t*t+b;}return -c/2*((--t)*(t-2)-1)+b;},easeInStrong:function(t,b,c,d){return c*(t/=d)*t*t*t+b;},easeOutStrong:function(t,b,c,d){return -c*((t=t/d-1)*t*t*t-1)+b;},easeBothStrong:function(t,b,c,d){if((t/=d/2)<1){return c/2*t*t*t*t+b;}return -c/2*((t-=2)*t*t*t-2)+b;},elasticIn:function(t,b,c,d,a,p){if(t==0){return b;}if((t/=d)==1){return b+c;}if(!p){p=d*0.3;}if(!a||a<Math.abs(c)){a=c;var s=p/4;}else{var s=p/(2*Math.PI)*Math.asin(c/a);}return -(a*Math.pow(2,10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p))+b;},elasticOut:function(t,b,c,d,a,p){if(t==0){return b;}if((t/=d)==1){return b+c;}if(!p){p=d*0.3;}if(!a||a<Math.abs(c)){a=c;var s=p/4;}else{var s=p/(2*Math.PI)*Math.asin(c/a);}return a*Math.pow(2,-10*t)*Math.sin((t*d-s)*(2*Math.PI)/p)+c+b;},elasticBoth:function(t,b,c,d,a,p){if(t==0){return b;}if((t/=d/2)==2){return b+c;}if(!p){p=d*(0.3*1.5);}if(!a||a<Math.abs(c)){a=c;var s=p/4;}else{var s=p/(2*Math.PI)*Math.asin(c/a);}if(t<1){return -0.5*(a*Math.pow(2,10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p))+b;}return a*Math.pow(2,-10*(t-=1))*Math.sin((t*d-s)*(2*Math.PI)/p)*0.5+c+b;},backIn:function(t,b,c,d,s){if(typeof s=="undefined"){s=1.70158;}return c*(t/=d)*t*((s+1)*t-s)+b;},backOut:function(t,b,c,d,s){if(typeof s=="undefined"){s=1.70158;}return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b;},backBoth:function(t,b,c,d,s){if(typeof s=="undefined"){s=1.70158;}if((t/=d/2)<1){return c/2*(t*t*(((s*=(1.525))+1)*t-s))+b;}return c/2*((t-=2)*t*(((s*=(1.525))+1)*t+s)+2)+b;},bounceIn:function(t,b,c,d){return c-YAHOO.util.Easing.bounceOut(d-t,0,c,d)+b;},bounceOut:function(t,b,c,d){if((t/=d)<(1/2.75)){return c*(7.5625*t*t)+b;}else{if(t<(2/2.75)){return c*(7.5625*(t-=(1.5/2.75))*t+0.75)+b;}else{if(t<(2.5/2.75)){return c*(7.5625*(t-=(2.25/2.75))*t+0.9375)+b;}}}return c*(7.5625*(t-=(2.625/2.75))*t+0.984375)+b;},bounceBoth:function(t,b,c,d){if(t<d/2){return YAHOO.util.Easing.bounceIn(t*2,0,c,d)*0.5+b;}return YAHOO.util.Easing.bounceOut(t*2-d,0,c,d)*0.5+c*0.5+b;}};(function(){YAHOO.util.Motion=function(el,_b2,_b3,_b4){if(el){YAHOO.util.Motion.superclass.constructor.call(this,el,_b2,_b3,_b4);}};YAHOO.extend(YAHOO.util.Motion,YAHOO.util.ColorAnim);var Y=YAHOO.util;var _b6=Y.Motion.superclass;var _b7=Y.Motion.prototype;_b7.toString=function(){var el=this.getEl();var id=el.id||el.tagName;return ("Motion "+id);};_b7.patterns.points=/^points$/i;_b7.setAttribute=function(_ba,val,_bc){if(this.patterns.points.test(_ba)){_bc=_bc||"px";_b6.setAttribute.call(this,"left",val[0],_bc);_b6.setAttribute.call(this,"top",val[1],_bc);}else{_b6.setAttribute.call(this,_ba,val,_bc);}};_b7.getAttribute=function(_bd){if(this.patterns.points.test(_bd)){var val=[_b6.getAttribute.call(this,"left"),_b6.getAttribute.call(this,"top")];}else{val=_b6.getAttribute.call(this,_bd);}return val;};_b7.doMethod=function(_bf,_c0,end){var val=null;if(this.patterns.points.test(_bf)){var t=this.method(this.currentFrame,0,100,this.totalFrames)/100;val=Y.Bezier.getPosition(this.runtimeAttributes[_bf],t);}else{val=_b6.doMethod.call(this,_bf,_c0,end);}return val;};_b7.setRuntimeAttribute=function(_c4){if(this.patterns.points.test(_c4)){var el=this.getEl();var _c6=this.attributes;var _c7;var _c8=_c6["points"]["control"]||[];var end;var i,len;if(_c8.length>0&&!(_c8[0] instanceof Array)){_c8=[_c8];}else{var tmp=[];for(i=0,len=_c8.length;i<len;++i){tmp[i]=_c8[i];}_c8=tmp;}if(Y.Dom.getStyle(el,"position")=="static"){Y.Dom.setStyle(el,"position","relative");}if(_cd(_c6["points"]["from"])){Y.Dom.setXY(el,_c6["points"]["from"]);}else{Y.Dom.setXY(el,Y.Dom.getXY(el));}_c7=this.getAttribute("points");if(_cd(_c6["points"]["to"])){end=_ce.call(this,_c6["points"]["to"],_c7);var _cf=Y.Dom.getXY(this.getEl());for(i=0,len=_c8.length;i<len;++i){_c8[i]=_ce.call(this,_c8[i],_c7);}}else{if(_cd(_c6["points"]["by"])){end=[_c7[0]+_c6["points"]["by"][0],_c7[1]+_c6["points"]["by"][1]];for(i=0,len=_c8.length;i<len;++i){_c8[i]=[_c7[0]+_c8[i][0],_c7[1]+_c8[i][1]];}}}this.runtimeAttributes[_c4]=[_c7];if(_c8.length>0){this.runtimeAttributes[_c4]=this.runtimeAttributes[_c4].concat(_c8);}this.runtimeAttributes[_c4][this.runtimeAttributes[_c4].length]=end;}else{_b6.setRuntimeAttribute.call(this,_c4);}};var _ce=function(val,_d1){var _d2=Y.Dom.getXY(this.getEl());val=[val[0]-_d2[0]+_d1[0],val[1]-_d2[1]+_d1[1]];return val;};var _cd=function(_d3){return (typeof _d3!=="undefined");};})();(function(){YAHOO.util.Scroll=function(el,_d5,_d6,_d7){if(el){YAHOO.util.Scroll.superclass.constructor.call(this,el,_d5,_d6,_d7);}};YAHOO.extend(YAHOO.util.Scroll,YAHOO.util.ColorAnim);var Y=YAHOO.util;var _d9=Y.Scroll.superclass;var _da=Y.Scroll.prototype;_da.toString=function(){var el=this.getEl();var id=el.id||el.tagName;return ("Scroll "+id);};_da.doMethod=function(_dd,_de,end){var val=null;if(_dd=="scroll"){val=[this.method(this.currentFrame,_de[0],end[0]-_de[0],this.totalFrames),this.method(this.currentFrame,_de[1],end[1]-_de[1],this.totalFrames)];}else{val=_d9.doMethod.call(this,_dd,_de,end);}return val;};_da.getAttribute=function(_e1){var val=null;var el=this.getEl();if(_e1=="scroll"){val=[el.scrollLeft,el.scrollTop];}else{val=_d9.getAttribute.call(this,_e1);}return val;};_da.setAttribute=function(_e4,val,_e6){var el=this.getEl();if(_e4=="scroll"){el.scrollLeft=val[0];el.scrollTop=val[1];}else{_d9.setAttribute.call(this,_e4,val,_e6);}};})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.2.0",build:"127"});
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/ext-all.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/ext-all.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,254 @@
+/*
+ * Ext JS Library 1.0
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://www.extjs.com/license
+ */
+
+Ext.DomHelper=function(){var _1=null;var _2=/^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i;var _3=function(o){if(typeof o=="string"){return o;}var b="";if(!o.tag){o.tag="div";}b+="<"+o.tag;for(var _6 in o){if(_6=="tag"||_6=="children"||_6=="cn"||_6=="html"||typeof o[_6]=="function"){continue;}if(_6=="style"){var s=o["style"];if(typeof s=="function"){s=s.call();}if(typeof s=="string"){b+=" style=\""+s+"\"";}else{if(typeof s=="object"){b+=" style=\"";for(var _8 in s){if(typeof s[_8]!="function"){b+=_8+":"+s[_8]+";";}}b+="\"";}}}else{if(_6=="cls"){b+=" class=\""+o["cls"]+"\"";}else{if(_6=="htmlFor"){b+=" for=\""+o["htmlFor"]+"\"";}else{b+=" "+_6+"=\""+o[_6]+"\"";}}}}if(_2.test(o.tag)){b+="/>";}else{b+=">";var cn=o.children||o.cn;if(cn){if(cn instanceof Array){for(var i=0,_b=cn.length;i<_b;i++){b+=_3(cn[i],b);}}else{b+=_3(cn,b);}}if(o.html){b+=o.html;}b+="</"+o.tag+">";}return b;};var _c=function(o,_e){var el=document.createElement(o.tag);var _10=el.setAttribute?true:false;for(var _11 in o){if(_11=="tag"||_11=="children"||_11=="cn"||_11=="html"||_11=="style"||typeof o[_11]=="function"){continue;}if(_11=="cls"){el.className=o["cls"];}else{if(_10){el.setAttribute(_11,o[_11]);}else{el[_11]=o[_11];}}}Ext.DomHelper.applyStyles(el,o.style);var cn=o.children||o.cn;if(cn){if(cn instanceof Array){for(var i=0,len=cn.length;i<len;i++){_c(cn[i],b);}}else{_c(cn,b);}}if(o.html){el.innerHTML=o.html;}if(_e){_e.appendChild(el);}return el;};var _15=function(_16,s,h,e){_1.innerHTML=[s,h,e].join("");var i=-1,el=_1;while(++i<_16){el=el.firstChild;}return el;};var ts="<table>",te="</table>",tbs=ts+"<tbody>",tbe="</tbody>"+te,trs=tbs+"<tr>",tre="</tr>"+tbe;var _22=function(tag,_24,el,_26){if(!_1){_1=document.createElement("div");}var _27;var _28=null;if(tag=="td"){if(_24=="afterbegin"||_24=="beforeend"){return;}if(_24=="beforebegin"){_28=el;el=el.parentNode;}else{_28=el.nextSibling;el=el.parentNode;}_27=_15(4,trs,_26,tre);}else{if(tag=="tr"){if(_24=="beforebegin"){_28=el;el=el.parentNode;_27=_15(3,tbs,_26,tbe);}else{if(_24=="afterend"){_28=el.nextSibling;el=el.parentNode;_27=_15(3,tbs,_26,tbe);}else{if(_24=="afterbegin"){_28=el.firstChild;}_27=_15(4,trs,_26,tre);}}}else{if(tag=="tbody"){if(_24=="beforebegin"){_28=el;el=el.parentNode;_27=_15(2,ts,_26,te);}else{if(_24=="afterend"){_28=el.nextSibling;el=el.parentNode;_27=_15(2,ts,_26,te);}else{if(_24=="afterbegin"){_28=el.firstChild;}_27=_15(3,tbs,_26,tbe);}}}else{if(_24=="beforebegin"||_24=="afterend"){return;}if(_24=="afterbegin"){_28=el.firstChild;}_27=_15(2,ts,_26,te);}}}el.insertBefore(_27,_28);return _27;};return {useDom:false,markup:function(o){return _3(o);},applyStyles:function(el,_2b){if(_2b){el=Ext.fly(el);if(typeof _2b=="string"){var re=/\s?([a-z\-]*)\:\s?([^;]*);?/gi;var _2d;while((_2d=re.exec(_2b))!=null){el.setStyle(_2d[1],_2d[2]);}}else{if(typeof _2b=="object"){for(var _2e in _2b){el.setStyle(_2e,_2b[_2e]);}}else{if(typeof _2b=="function"){Ext.DomHelper.applyStyles(el,_2b.call());}}}}},insertHtml:function(_2f,el,_31){_2f=_2f.toLowerCase();if(el.insertAdjacentHTML){var tag=el.tagName.toLowerCase();if(tag=="table"||tag=="tbody"||tag=="tr"||tag=="td"){var rs;if(rs=_22(tag,_2f,el,_31)){return rs;}}switch(_2f){case "beforebegin":el.insertAdjacentHTML(_2f,_31);return el.previousSibling;case "afterbegin":el.insertAdjacentHTML(_2f,_31);return el.firstChild;case "beforeend":el.insertAdjacentHTML(_2f,_31);return el.lastChild;case "afterend":el.insertAdjacentHTML(_2f,_31);return el.nextSibling;}throw "Illegal insertion point -> \""+_2f+"\"";}var _34=el.ownerDocument.createRange();var _35;switch(_2f){case "beforebegin":_34.setStartBefore(el);_35=_34.createContextualFragment(_31);el.parentNode.insertBefore(_35,el);return el.previousSibling;case "afterbegin":if(el.firstChild){_34.setStartBefore(el.firstChild);}else{_34.selectNodeContents(el);_34.collapse(true);}_35=_34.createContextualFragment(_31);el.insertBefore(_35,el.firstChild);return el.firstChild;case "beforeend":if(el.lastChild){_34.setStartAfter(el.lastChild);}else{_34.selectNodeContents(el);_34.collapse(false);}_35=_34.createContextualFragment(_31);el.appendChild(_35);return el.lastChild;case "afterend":_34.setStartAfter(el);_35=_34.createContextualFragment(_31);el.parentNode.insertBefore(_35,el.nextSibling);return el.nextSibling;}throw "Illegal insertion point -> \""+_2f+"\"";},insertBefore:function(el,o,_38){return this.doInsert(el,o,_38,"beforeBegin");},insertAfter:function(el,o,_3b){return this.doInsert(el,o,_3b,"afterEnd","nextSibling");},insertFirst:function(el,o,_3e){return this.doInsert(el,o,_3e,"afterBegin");},doInsert:function(el,o,_41,pos,_43){el=Ext.getDom(el);var _44;if(this.useDom){_44=_c(o,null);el.parentNode.insertBefore(_44,_43?el[_43]:el);}else{var _45=_3(o);_44=this.insertHtml(pos,el,_45);}return _41?Ext.get(_44,true):_44;},append:function(el,o,_48){el=Ext.getDom(el);var _49;if(this.useDom){_49=_c(o,null);el.appendChild(_49);}else{var _4a=_3(o);_49=this.insertHtml("beforeEnd",el,_4a);}return _48?Ext.get(_49,true):_49;},overwrite:function(el,o,_4d){el=Ext.getDom(el);el.innerHTML=_3(o);return _4d?Ext.get(el.firstChild,true):el.firstChild;},createTemplate:function(o){var _4f=_3(o);return new Ext.Template(_4f);}};}();
+
+Ext.Template=function(_1){if(_1 instanceof Array){_1=_1.join("");}else{if(arguments.length>1){_1=Array.prototype.join.call(arguments,"");}}this.html=_1;};Ext.Template.prototype={applyTemplate:function(_2){if(this.compiled){return this.compiled(_2);}var _3=this.disableFormats!==true;var fm=Ext.util.Format,_5=this;var fn=function(m,_8,_9,_a){if(_9&&_3){if(_9.substr(0,5)=="this."){return _5.call(_9.substr(5),_2[_8]);}else{if(_a){var re=/^\s*['"](.*)["']\s*$/;_a=_a.split(",");for(var i=0,_d=_a.length;i<_d;i++){_a[i]=_a[i].replace(re,"$1");}_a=[_2[_8]].concat(_a);}else{_a=[_2[_8]];}return fm[_9].apply(fm,_a);}}else{return _2[_8]!==undefined?_2[_8]:"";}};return this.html.replace(this.re,fn);},set:function(_e,_f){this.html=_e;this.compiled=null;if(_f){this.compile();}return this;},disableFormats:false,re:/\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,compile:function(){var fm=Ext.util.Format;var _11=this.disableFormats!==true;var sep=Ext.isGecko?"+":",";var fn=function(m,_15,_16,_17){if(_16&&_11){_17=_17?","+_17:"";if(_16.substr(0,5)!="this."){_16="fm."+_16+"(";}else{_16="this.call(\""+_16.substr(5)+"\", ";_17="";}}else{_17="",_16="(values['"+_15+"'] == undefined ? '' : ";}return "'"+sep+_16+"values['"+_15+"']"+_17+")"+sep+"'";};var _18;if(Ext.isGecko){_18="this.compiled = function(values){ return '"+this.html.replace(/(\r\n|\n)/g,"\\n").replace("'","\\'").replace(this.re,fn)+"';};";}else{_18=["this.compiled = function(values){ return ['"];_18.push(this.html.replace(/(\r\n|\n)/g,"\\n").replace("'","\\'").replace(this.re,fn));_18.push("'].join('');};");_18=_18.join("");}eval(_18);return this;},call:function(_19,_1a){return this[_19](_1a);},insertBefore:function(el,_1c,_1d){el=Ext.getDom(el);var _1e=Ext.DomHelper.insertHtml("beforeBegin",el,this.applyTemplate(_1c));return _1d?Ext.get(_1e,true):_1e;},insertAfter:function(el,_20,_21){el=Ext.getDom(el);var _22=Ext.DomHelper.insertHtml("afterEnd",el,this.applyTemplate(_20));return _21?Ext.get(_22,true):_22;},append:function(el,_24,_25){el=Ext.getDom(el);var _26=Ext.DomHelper.insertHtml("beforeEnd",el,this.applyTemplate(_24));return _25?Ext.get(_26,true):_26;},overwrite:function(el,_28,_29){el=Ext.getDom(el);el.innerHTML=this.applyTemplate(_28);return _29?Ext.get(el.firstChild,true):el.firstChild;}};Ext.Template.prototype.apply=Ext.Template.prototype.applyTemplate;Ext.DomHelper.Template=Ext.Template;Ext.Template.from=function(el){el=Ext.getDom(el);return new Ext.Template(el.value||el.innerHTML);};Ext.MasterTemplate=function(){Ext.MasterTemplate.superclass.constructor.apply(this,arguments);this.originalHtml=this.html;var st={};var m,re=this.subTemplateRe;re.lastIndex=0;var _2e=0;while(m=re.exec(this.html)){var _2f=m[1],_30=m[2];st[_2e]={name:_2f,index:_2e,buffer:[],tpl:new Ext.Template(_30)};if(_2f){st[_2f]=st[_2e];}st[_2e].tpl.compile();st[_2e].tpl.call=this.call.createDelegate(this);_2e++;}this.subCount=_2e;this.subs=st;};Ext.extend(Ext.MasterTemplate,Ext.Template,{subTemplateRe:/<tpl(?:\sname="([\w-]+)")?>((?:.|\n)*?)<\/tpl>/gi,add:function(_31,_32){if(arguments.length==1){_32=arguments[0];_31=0;}var s=this.subs[_31];s.buffer[s.buffer.length]=s.tpl.apply(_32);return this;},fill:function(_34,_35,_36){var a=arguments;if(a.length==1||(a.length==2&&typeof a[1]=="boolean")){_35=a[0];_34=0;_36=a[1];}if(_36){this.reset();}for(var i=0,len=_35.length;i<len;i++){this.add(_34,_35[i]);}return this;},reset:function(){var s=this.subs;for(var i=0;i<this.subCount;i++){s[i].buffer=[];}return this;},applyTemplate:function(_3c){var s=this.subs;var _3e=-1;this.html=this.originalHtml.replace(this.subTemplateRe,function(m,_40){return s[++_3e].buffer.join("");});return Ext.MasterTemplate.superclass.applyTemplate.call(this,_3c);},apply:function(){return this.applyTemplate.apply(this,arguments);},compile:function(){return this;}});Ext.MasterTemplate.prototype.addAll=Ext.MasterTemplate.prototype.fill;Ext.MasterTemplate.from=function(el){el=Ext.getDom(el);return new Ext.MasterTemplate(el.value||el.innerHTML);};
+
+Ext.DomQuery=function(){var _1={},_2={},_3={};var _4=/\S/;var _5=/^\s+|\s+$/g;var _6=/\{(\d+)\}/g;var _7=/^(\s?[\/>]\s?|\s|$)/;var _8=/^(#)?([\w-\*]+)/;function child(p,_a){var i=0;var n=p.firstChild;while(n){if(n.nodeType==1){if(++i==_a){return n;}}n=n.nextSibling;}return null;}function next(n){while((n=n.nextSibling)&&n.nodeType!=1){}return n;}function prev(n){while((n=n.previousSibling)&&n.nodeType!=1){}return n;}function clean(d){var n=d.firstChild,ni=-1;while(n){var nx=n.nextSibling;if(n.nodeType==3&&!_4.test(n.nodeValue)){d.removeChild(n);}else{n.nodeIndex=++ni;}n=nx;}return this;}function byClassName(c,a,v,re,cn){if(!v){return c;}var r=[];for(var i=0,ci;ci=c[i];i++){cn=ci.className;if(cn&&(" "+cn+" ").indexOf(v)!=-1){r[r.length]=ci;}}return r;}function attrValue(n,_1c){if(!n.tagName&&typeof n.length!="undefined"){n=n[0];}if(!n){return null;}if(_1c=="for"){return n.htmlFor;}if(_1c=="class"||_1c=="className"){return n.className;}return n.getAttribute(_1c)||n[_1c];}function getNodes(ns,_1e,_1f){var _20=[],cs;if(!ns){return _20;}_1e=_1e?_1e.replace(_5,""):"";_1f=_1f||"*";if(typeof ns.getElementsByTagName!="undefined"){ns=[ns];}if(_1e!="/"&&_1e!=">"){for(var i=0,ni;ni=ns[i];i++){cs=ni.getElementsByTagName(_1f);for(var j=0,ci;ci=cs[j];j++){_20[_20.length]=ci;}}}else{for(var i=0,ni;ni=ns[i];i++){var cn=ni.getElementsByTagName(_1f);for(var j=0,cj;cj=cn[j];j++){if(cj.parentNode==ni){_20[_20.length]=cj;}}}}return _20;}function concat(a,b){if(b.slice){return a.concat(b);}for(var i=0,l=b.length;i<l;i++){a[a.length]=b[i];}return a;}function byTag(cs,_2d){if(cs.tagName||cs==document){cs=[cs];}if(!_2d){return cs;}var r=[];_2d=_2d.toLowerCase();for(var i=0,ci;ci=cs[i];i++){if(ci.nodeType==1&&ci.tagName.toLowerCase()==_2d){r[r.length]=ci;}}return r;}function byId(cs,_32,id){if(cs.tagName||cs==document){cs=[cs];}if(!id){return cs;}var r=[];for(var i=0,ci;ci=cs[i];i++){if(ci&&ci.id==id){r[r.length]=ci;return r;}}return r;}function byAttribute(cs,_38,_39,op,_3b){var r=[],st=_3b=="{";var f=Ext.DomQuery.operators[op];for(var i=0;ci=cs[i];i++){var a;if(st){a=Ext.DomQuery.getStyle(ci,_38);}else{if(_38=="class"||_38=="className"){a=ci.className;}else{if(_38=="for"){a=ci.htmlFor;}else{if(_38=="href"){a=ci.getAttribute("href",2);}else{a=ci.getAttribute(_38);}}}}if((f&&f(a,_39))||(!f&&a)){r[r.length]=ci;}}return r;}function byPseudo(cs,_42,_43){return Ext.DomQuery.pseudos[_42](cs,_43);}var _44=window.ActiveXObject?true:false;var key=30803;function nodupIEXml(cs){var d=++key;cs[0].setAttribute("_nodup",d);var r=[cs[0]];for(var i=1,len=cs.length;i<len;i++){var c=cs[i];if(!c.getAttribute("_nodup")!=d){c.setAttribute("_nodup",d);r[r.length]=c;}}for(var i=0,len=cs.length;i<len;i++){cs[i].removeAttribute("_nodup");}return r;}function nodup(cs){if(!cs){return [];}var len=cs.length,c,i,r=cs,cj;if(!len||typeof cs.nodeType!="undefined"||len==1){return cs;}if(_44&&typeof cs[0].selectSingleNode!="undefined"){return nodupIEXml(cs);}var d=++key;cs[0]._nodup=d;for(i=1;c=cs[i];i++){if(c._nodup!=d){c._nodup=d;}else{r=[];for(var j=0;j<i;j++){r[r.length]=cs[j];}for(j=i+1;cj=cs[j];j++){if(cj._nodup!=d){cj._nodup=d;r[r.length]=cj;}}return r;}}return r;}function quickDiffIEXml(c1,c2){var d=++key;for(var i=0,len=c1.length;i<len;i++){c1[i].setAttribute("_qdiff",d);}var r=[];for(var i=0,len=c2.length;i<len;i++){if(c2[i].getAttribute("_qdiff")!=d){r[r.length]=c2[i];}}for(var i=0,len=c1.length;i<len;i++){c1[i].removeAttribute("_qdiff");}return r;}function quickDiff(c1,c2){var _5c=c1.length;if(!_5c){return c2;}if(_44&&c1[0].selectSingleNode){return quickDiffIEXml(c1,c2);}var d=++key;for(var i=0;i<_5c;i++){c1[i]._qdiff=d;}var r=[];for(var i=0,len=c2.length;i<len;i++){if(c2[i]._qdiff!=d){r[r.length]=c2[i];}}return r;}function quickId(ns,_62,_63,id){if(ns==_63){var d=_63.ownerDocument||_63;return d.getElementById(id);}ns=getNodes(ns,_62,"*");return byId(ns,null,id);}return {getStyle:function(el,_67){return Ext.fly(el).getStyle(_67);},compile:function(_68,_69){while(_68.substr(0,1)=="/"){_68=_68.substr(1);}_69=_69||"select";var fn=["var f = function(root){\n var mode; var n = root || document;\n"];var q=_68,_6c,lq;var tk=Ext.DomQuery.matchers;var _6f=tk.length;var mm;while(q&&lq!=q){lq=q;var tm=q.match(_8);if(_69=="select"){if(tm){if(tm[1]=="#"){fn[fn.length]="n = quickId(n, mode, root, \""+tm[2]+"\");";}else{fn[fn.length]="n = getNodes(n, mode, \""+tm[2]+"\");";}q=q.replace(tm[0],"");}else{if(q.substr(0,1)!="@"){fn[fn.length]="n = getNodes(n, mode, \"*\");";}}}else{if(tm){if(tm[1]=="#"){fn[fn.length]="n = byId(n, null, \""+tm[2]+"\");";}else{fn[fn.length]="n = byTag(n, \""+tm[2]+"\");";}q=q.replace(tm[0],"");}}while(!(mm=q.match(_7))){var _72=false;for(var j=0;j<_6f;j++){var t=tk[j];var m=q.match(t.re);if(m){fn[fn.length]=t.select.replace(_6,function(x,i){return m[i];});q=q.replace(m[0],"");_72=true;break;}}if(!_72){throw "Error parsing selector, parsing failed at \""+q+"\"";}}if(mm[1]){fn[fn.length]="mode=\""+mm[1]+"\";";q=q.replace(mm[1],"");}}fn[fn.length]="return nodup(n);\n}";eval(fn.join(""));return f;},select:function(_78,_79,_7a){if(!_79||_79==document){_79=document;}if(typeof _79=="string"){_79=document.getElementById(_79);}var _7b=_78.split(",");var _7c=[];for(var i=0,len=_7b.length;i<len;i++){var p=_7b[i].replace(_5,"");if(!_1[p]){_1[p]=Ext.DomQuery.compile(p);if(!_1[p]){throw p+" is not a valid selector";}}var _80=_1[p](_79);if(_80&&_80!=document){_7c=_7c.concat(_80);}}return _7c;},selectNode:function(_81,_82){return Ext.DomQuery.select(_81,_82)[0];},selectValue:function(_83,_84,_85){_83=_83.replace(_5,"");if(!_3[_83]){_3[_83]=Ext.DomQuery.compile(_83,"select");}var n=_3[_83](_84);n=n[0]?n[0]:n;var v=(n&&n.firstChild?n.firstChild.nodeValue:null);return (v===null?_85:v);},selectNumber:function(_88,_89,_8a){var v=Ext.DomQuery.selectValue(_88,_89,_8a||0);return parseFloat(v);},is:function(el,ss){if(typeof el=="string"){el=document.getElementById(el);}var _8e=(el instanceof Array);var _8f=Ext.DomQuery.filter(_8e?el:[el],ss);return _8e?(_8f.length==el.length):(_8f.length>0);},filter:function(els,ss,_92){ss=ss.replace(_5,"");if(!_2[ss]){_2[ss]=Ext.DomQuery.compile(ss,"simple");}var _93=_2[ss](els);return _92?quickDiff(_93,els):_93;},matchers:[{re:/^\.([\w-]+)/,select:"n = byClassName(n, null, \" {1} \");"},{re:/^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,select:"n = byPseudo(n, \"{1}\", \"{2}\");"},{re:/^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,select:"n = byAttribute(n, \"{2}\", \"{4}\", \"{3}\", \"{1}\");"},{re:/^#([\w-]+)/,select:"n = byId(n, null, \"{1}\");"},{re:/^@([\w-]+)/,select:"return {firstChild:{nodeValue:attrValue(n, \"{1}\")}};"}],operators:{"=":function(a,v){return a==v;},"!=":function(a,v){return a!=v;},"^=":function(a,v){return a&&a.substr(0,v.length)==v;},"$=":function(a,v){return a&&a.substr(a.length-v.length)==v;},"*=":function(a,v){return a&&a.indexOf(v)!==-1;},"%=":function(a,v){return (a%v)==0;}},pseudos:{"first-child":function(c){var r=[],n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.previousSibling)&&n.nodeType!=1){}if(!n){r[r.length]=ci;}}return r;},"last-child":function(c){var r=[];for(var i=0,ci;ci=n=c[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(!n){r[r.length]=ci;}}return r;},"nth-child":function(c,a){var r=[];if(a!="odd"&&a!="even"){for(var i=0,ci;ci=c[i];i++){var m=child(ci.parentNode,a);if(m==ci){r[r.length]=m;}}return r;}var p;for(var i=0,l=c.length;i<l;i++){var cp=c[i].parentNode;if(cp!=p){clean(cp);p=cp;}}for(var i=0,ci;ci=c[i];i++){var m=false;if(a=="odd"){m=((ci.nodeIndex+1)%2==1);}else{if(a=="even"){m=((ci.nodeIndex+1)%2==0);}}if(m){r[r.length]=ci;}}return r;},"only-child":function(c){var r=[];for(var i=0,ci;ci=c[i];i++){if(!prev(ci)&&!next(ci)){r[r.length]=ci;}}return r;},"empty":function(c){var r=[];for(var i=0,ci;ci=c[i];i++){var cns=ci.childNodes,j=0,cn,_bd=true;while(cn=cns[j]){++j;if(cn.nodeType==1||cn.nodeType==3){_bd=false;break;}}if(_bd){r[r.length]=ci;}}return r;},"contains":function(c,v){var r=[];for(var i=0,ci;ci=c[i];i++){if(ci.innerHTML.indexOf(v)!==-1){r[r.length]=ci;}}return r;},"nodeValue":function(c,v){var r=[];for(var i=0,ci;ci=c[i];i++){if(ci.firstChild&&ci.firstChild.nodeValue==v){r[r.length]=ci;}}return r;},"checked":function(c){var r=[];for(var i=0,ci;ci=c[i];i++){if(ci.checked==true){r[r.length]=ci;}}return r;},"not":function(c,ss){return Ext.DomQuery.filter(c,ss,true);},"odd":function(c){return this["nth-child"](c,"odd");},"even":function(c){return this["nth-child"](c,"even");},"nth":function(c,a){return c[a-1]||[];},"first":function(c){return c[0]||[];},"last":function(c){return c[c.length-1]||[];},"has":function(c,ss){var s=Ext.DomQuery.select;var r=[];for(var i=0,ci;ci=c[i];i++){if(s(ss,ci).length>0){r[r.length]=ci;}}return r;},"next":function(c,ss){var is=Ext.DomQuery.is;var r=[];for(var i=0,ci;ci=c[i];i++){var n=next(ci);if(n&&is(n,ss)){r[r.length]=ci;}}return r;},"prev":function(c,ss){var is=Ext.DomQuery.is;var r=[];for(var i=0,ci;ci=c[i];i++){var n=prev(ci);if(n&&is(n,ss)){r[r.length]=ci;}}return r;}}};}();Ext.query=Ext.DomQuery.select;
+
+Ext.util.Observable=function(){if(this.listeners){this.on(this.listeners);delete this.listeners;}};Ext.util.Observable.prototype={fireEvent:function(){var ce=this.events[arguments[0].toLowerCase()];if(typeof ce=="object"){return ce.fire.apply(ce,Array.prototype.slice.call(arguments,1));}else{return true;}},filterOptRe:/^(?:scope|delay|buffer|single)$/,addListener:function(_2,fn,_4,o){if(typeof _2=="object"){o=_2;for(var e in o){if(this.filterOptRe.test(e)){continue;}if(typeof o[e]=="function"){this.addListener(e,o[e],o.scope,o);}else{this.addListener(e,o[e].fn,o[e].scope,o[e]);}}return;}o=(!o||typeof o=="boolean")?{}:o;_2=_2.toLowerCase();var ce=this.events[_2]||true;if(typeof ce=="boolean"){ce=new Ext.util.Event(this,_2);this.events[_2]=ce;}ce.addListener(fn,_4,o);},removeListener:function(_8,fn,_a){var ce=this.events[_8.toLowerCase()];if(typeof ce=="object"){ce.removeListener(fn,_a);}},purgeListeners:function(){for(var _c in this.events){if(typeof this.events[_c]=="object"){this.events[_c].clearListeners();}}},relayEvents:function(o,_e){var _f=function(_10){return function(){return this.fireEvent.apply(this,Ext.combine(_10,Array.prototype.slice.call(arguments,0)));};};for(var i=0,len=_e.length;i<len;i++){var _13=_e[i];if(!this.events[_13]){this.events[_13]=true;}o.on(_13,_f(_13),this);}},addEvents:function(o){if(!this.events){this.events={};}Ext.applyIf(this.events,o);},hasListener:function(_15){var e=this.events[_15];return typeof e=="object"&&e.listeners.length>0;}};Ext.util.Observable.prototype.on=Ext.util.Observable.prototype.addListener;Ext.util.Observable.prototype.un=Ext.util.Observable.prototype.removeListener;Ext.util.Observable.capture=function(o,fn,_19){o.fireEvent=o.fireEvent.createInterceptor(fn,_19);};Ext.util.Observable.releaseCapture=function(o){o.fireEvent=Ext.util.Observable.prototype.fireEvent;};(function(){var _1b=function(h,o,_1e){var _1f=new Ext.util.DelayedTask();return function(){_1f.delay(o.buffer,h,_1e,Array.prototype.slice.call(arguments,0));};};var _20=function(h,e,fn,_24){return function(){e.removeListener(fn,_24);return h.apply(_24,arguments);};};var _25=function(h,o,_28){return function(){var _29=Array.prototype.slice.call(arguments,0);setTimeout(function(){h.apply(_28,_29);},o.delay||10);};};Ext.util.Event=function(obj,_2b){this.name=_2b;this.obj=obj;this.listeners=[];};Ext.util.Event.prototype={addListener:function(fn,_2d,_2e){var o=_2e||{};_2d=_2d||this.obj;if(!this.isListening(fn,_2d)){var l={fn:fn,scope:_2d,options:o};var h=fn;if(o.delay){h=_25(h,o,_2d);}if(o.single){h=_20(h,this,fn,_2d);}if(o.buffer){h=_1b(h,o,_2d);}l.fireFn=h;if(!this.firing){this.listeners.push(l);}else{this.listeners=this.listeners.slice(0);this.listeners.push(l);}}},findListener:function(fn,_33){_33=_33||this.obj;var ls=this.listeners;for(var i=0,len=ls.length;i<len;i++){var l=ls[i];if(l.fn==fn&&l.scope==_33){return i;}}return -1;},isListening:function(fn,_39){return this.findListener(fn,_39)!=-1;},removeListener:function(fn,_3b){var _3c;if((_3c=this.findListener(fn,_3b))!=-1){if(!this.firing){this.listeners.splice(_3c,1);}else{this.listeners=this.listeners.slice(0);this.listeners.splice(_3c,1);}return true;}return false;},clearListeners:function(){this.listeners=[];},fire:function(){var ls=this.listeners,_3e,len=ls.length;if(len>0){this.firing=true;var _40=Array.prototype.slice.call(arguments,0);for(var i=0;i<len;i++){var l=ls[i];if(l.fireFn.apply(l.scope,arguments)===false){this.firing=false;return false;}}this.firing=false;}return true;}};})();
+
+Ext.EventManager=function(){var _1,_2,_3=false;var _4,_5,_6,_7;var E=Ext.lib.Event;var D=Ext.lib.Dom;var _a=function(){if(!_3){_3=true;if(_2){clearInterval(_2);}if(Ext.isGecko||Ext.isOpera){document.removeEventListener("DOMContentLoaded",_a,false);}if(_1){_1.fire();_1.clearListeners();}}};var _b=function(){_1=new Ext.util.Event();if(Ext.isGecko||Ext.isOpera){document.addEventListener("DOMContentLoaded",_a,false);}else{if(Ext.isIE){document.write("<s"+"cript id=\"ie-deferred-loader\" defer=\"defer\" src=\"/"+"/:\"></s"+"cript>");E.on("ie-deferred-loader","readystatechange",function(){if(this.readyState=="complete"){_a();}});}else{if(Ext.isSafari){_2=setInterval(function(){var rs=document.readyState;if(rs=="complete"){_a();}},10);}}}E.on(window,"load",_a);};var _d=function(h,o){var _10=new Ext.util.DelayedTask(h);return function(e){e=new Ext.EventObjectImpl(e);_10.delay(o.buffer,h,null,[e]);};};var _12=function(h,el,_15,fn){return function(e){Ext.EventManager.removeListener(el,_15,fn);h(e);};};var _18=function(h,o){return function(e){e=new Ext.EventObjectImpl(e);setTimeout(function(){h(e);},o.delay||10);};};var _1c=function(_1d,_1e,opt,fn,_21){var o=(!opt||typeof opt=="boolean")?{}:opt;fn=fn||o.fn;_21=_21||o.scope;var el=Ext.getDom(_1d);if(!el){throw "Error listening for "+_1e+". Element "+_1d+" doesn't exist.";}var h=function(e){e=Ext.EventObject.setEvent(e);var t;if(o.delegate){t=e.getTarget(o.delegate,el);if(!t){return;}}else{t=e.target;}if(o.stopEvent===true){e.stopEvent();}if(o.preventDefault===true){e.preventDefault();}if(o.stopPropagation===true){e.stopPropagation();}if(o.normalized===false){e=e.browserEvent;}fn.call(_21||el,e,t,o);};if(o.delay){h=_18(h,o);}if(o.single){h=_12(h,el,_1e,fn);}if(o.buffer){h=_d(h,o);}fn._handlers=fn._handlers||[];fn._handlers.push([Ext.id(el),_1e,h]);E.on(el,_1e,h);if(_1e=="mousewheel"&&el.addEventListener){el.addEventListener("DOMMouseScroll",h,false);E.on(window,"unload",function(){el.removeEventListener("DOMMouseScroll",h,false);});}if(_1e=="mousedown"&&el==document){Ext.EventManager.stoppedMouseDownEvent.addListener(h);}return h;};var _27=function(el,_29,fn){var id=Ext.id(el),hds=fn._handlers;if(hds){for(var i=0,len=hds.length;i<len;i++){var h=hds[i];if(h[0]==id&&h[1]==_29){var hd=h[2];hds.splice(i,1);return E.un(el,_29,hd);}}}E.un(el,_29,fn);el=Ext.getDom(el);if(_29=="mousewheel"&&el.addEventListener){el.removeEventListener("DOMMouseScroll",fn,false);}if(_29=="mousedown"&&el==document){Ext.EventManager.stoppedMouseDownEvent.removeListener(fn);}};var _31=/^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized)$/;var pub={wrap:function(fn,_34,_35){return function(e){Ext.EventObject.setEvent(e);fn.call(_35?_34||window:window,Ext.EventObject,_34);};},addListener:function(_37,_38,fn,_3a,_3b){if(typeof _38=="object"){var o=_38;for(var e in o){if(_31.test(e)){continue;}if(typeof o[e]=="function"){_1c(_37,e,o,o[e],o.scope);}else{_1c(_37,e,o[e]);}}return;}return _1c(_37,_38,_3b,fn,_3a);},removeListener:function(_3e,_3f,fn){return _27(_3e,_3f,fn);},onDocumentReady:function(fn,_42,_43){if(_3){fn.call(_42||window,_42);return;}if(!_1){_b();}_1.addListener(fn,_42,_43);},onWindowResize:function(fn,_45,_46){if(!_4){_4=new Ext.util.Event();_5=new Ext.util.DelayedTask(function(){_4.fire(D.getViewWidth(),D.getViewHeight());});E.on(window,"resize",function(){if(Ext.isIE){_5.delay(50);}else{_4.fire(D.getViewWidth(),D.getViewHeight());}});}_4.addListener(fn,_45,_46);},onTextResize:function(fn,_48,_49){if(!_6){_6=new Ext.util.Event();var _4a=new Ext.Element(document.createElement("div"));_4a.dom.className="x-text-resize";_4a.dom.innerHTML="X";_4a.appendTo(document.body);_7=_4a.dom.offsetHeight;setInterval(function(){if(_4a.dom.offsetHeight!=_7){_6.fire(_7,_7=_4a.dom.offsetHeight);}},this.textResizeInterval);}_6.addListener(fn,_48,_49);},removeResizeListener:function(fn,_4c){if(_4){_4.removeListener(fn,_4c);}},fireResize:function(){if(_4){_4.fire(D.getViewWidth(),D.getViewHeight());}},ieDeferSrc:false,textResizeInterval:50};pub.on=pub.addListener;pub.un=pub.removeListener;pub.stoppedMouseDownEvent=new Ext.util.Event();return pub;}();Ext.onReady=Ext.EventManager.onDocumentReady;Ext.onReady(function(){var bd=Ext.get(document.body);if(!bd){return;}var cls=Ext.isIE?"ext-ie":Ext.isGecko?"ext-gecko":Ext.isOpera?"ext-opera":Ext.isSafari?"ext-safari":"";if(Ext.isBorderBox){cls+=" ext-border-box";}if(Ext.isStrict){cls+=" ext-strict";}bd.addClass(cls);});Ext.EventObject=function(){var E=Ext.lib.Event;var _50={63234:37,63235:39,63232:38,63233:40,63276:33,63277:34,63272:46,63273:36,63275:35};var _51=Ext.isIE?{1:0,4:1,2:2}:(Ext.isSafari?{1:0,2:1,3:2}:{0:0,1:1,2:2});Ext.EventObjectImpl=function(e){if(e){this.setEvent(e.browserEvent||e);}};Ext.EventObjectImpl.prototype={browserEvent:null,button:-1,shiftKey:false,ctrlKey:false,altKey:false,BACKSPACE:8,TAB:9,RETURN:13,ENTER:13,SHIFT:16,CONTROL:17,ESC:27,SPACE:32,PAGEUP:33,PAGEDOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46,F5:116,setEvent:function(e){if(e==this||(e&&e.browserEvent)){return e;}this.browserEvent=e;if(e){this.button=e.button?_51[e.button]:(e.which?e.which-1:-1);this.shiftKey=e.shiftKey;this.ctrlKey=e.ctrlKey||e.metaKey;this.altKey=e.altKey;this.keyCode=e.keyCode;this.charCode=e.charCode;this.target=E.getTarget(e);this.xy=E.getXY(e);}else{this.button=-1;this.shiftKey=false;this.ctrlKey=false;this.altKey=false;this.keyCode=0;this.charCode=0;this.target=null;this.xy=[0,0];}return this;},stopEvent:function(){if(this.browserEvent){if(this.browserEvent.type=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.fire(this);}E.stopEvent(this.browserEvent);}},preventDefault:function(){if(this.browserEvent){E.preventDefault(this.browserEvent);}},isNavKeyPress:function(){var k=this.keyCode;k=Ext.isSafari?(_50[k]||k):k;return (k>=33&&k<=40)||k==this.RETURN||k==this.TAB||k==this.ESC;},isSpecialKey:function(){var k=this.keyCode;return k==9||k==13||k==40||k==27||(k==16)||(k==17)||(k>=18&&k<=20)||(k>=33&&k<=35)||(k>=36&&k<=39)||(k>=44&&k<=45);},stopPropagation:function(){if(this.browserEvent){if(this.browserEvent.type=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.fire(this);}E.stopPropagation(this.browserEvent);}},getCharCode:function(){return this.charCode||this.keyCode;},getKey:function(){var k=this.keyCode||this.charCode;return Ext.isSafari?(_50[k]||k):k;},getPageX:function(){return this.xy[0];},getPageY:function(){return this.xy[1];},getTime:function(){if(this.browserEvent){return E.getTime(this.browserEvent);}return null;},getXY:function(){return this.xy;},getTarget:function(_57,_58,_59){return _57?Ext.fly(this.target).findParent(_57,_58,_59):this.target;},getRelatedTarget:function(){if(this.browserEvent){return E.getRelatedTarget(this.browserEvent);}return null;},getWheelDelta:function(){var e=this.browserEvent;var _5b=0;if(e.wheelDelta){_5b=e.wheelDelta/120;if(window.opera){_5b=-_5b;}}else{if(e.detail){_5b=-e.detail/3;}}return _5b;},hasModifier:function(){return ((this.ctrlKey||this.altKey)||this.shiftKey)?true:false;},within:function(el,_5d){var t=this[_5d?"getRelatedTarget":"getTarget"]();return t&&Ext.fly(el).contains(t);},getPoint:function(){return new Ext.lib.Point(this.xy[0],this.xy[1]);}};return new Ext.EventObjectImpl();}();
+
+(function(){var D=Ext.lib.Dom;var E=Ext.lib.Event;var A=Ext.lib.Anim;var _4={};var _5=/(-[a-z])/gi;var _6=function(m,a){return a.charAt(1).toUpperCase();};var _9=document.defaultView;Ext.Element=function(_a,_b){var _c=typeof _a=="string"?document.getElementById(_a):_a;if(!_c){return null;}if(!_b&&Ext.Element.cache[_c.id]){return Ext.Element.cache[_c.id];}this.dom=_c;this.id=_c.id||Ext.id(_c);};var El=Ext.Element;El.prototype={originalDisplay:"",visibilityMode:1,defaultUnit:"px",setVisibilityMode:function(_e){this.visibilityMode=_e;return this;},enableDisplayMode:function(_f){this.setVisibilityMode(El.DISPLAY);if(typeof _f!="undefined"){this.originalDisplay=_f;}return this;},findParent:function(_10,_11,_12){var p=this.dom,b=document.body,_15=0,dq=Ext.DomQuery,_17;_11=_11||50;if(typeof _11!="number"){_17=Ext.getDom(_11);_11=10;}while(p&&p.nodeType==1&&_15<_11&&p!=b&&p!=_17){if(dq.is(p,_10)){return _12?Ext.get(p):p;}_15++;p=p.parentNode;}return null;},findParentNode:function(_18,_19,_1a){var p=Ext.fly(this.dom.parentNode,"_internal");return p?p.findParent(_18,_19,_1a):null;},up:function(_1c,_1d){return this.findParentNode(_1c,_1d,true);},is:function(_1e){return Ext.DomQuery.is(this.dom,_1e);},animate:function(_1f,_20,_21,_22,_23){this.anim(_1f,{duration:_20,callback:_21,easing:_22},_23);return this;},anim:function(_24,opt,_26,_27,_28,cb){_26=_26||"run";opt=opt||{};var _2a=Ext.lib.Anim[_26](this.dom,_24,(opt.duration||_27)||0.35,(opt.easing||_28)||"easeOut",function(){Ext.callback(cb,this);Ext.callback(opt.callback,opt.scope||this,[this,opt]);},this);opt.anim=_2a;return _2a;},preanim:function(a,i){return !a[i]?false:(typeof a[i]=="object"?a[i]:{duration:a[i+1],callback:a[i+2],easing:a[i+3]});},clean:function(_2d){if(this.isCleaned&&_2d!==true){return this;}var ns=/\S/;var d=this.dom,n=d.firstChild,ni=-1;while(n){var nx=n.nextSibling;if(n.nodeType==3&&!ns.test(n.nodeValue)){d.removeChild(n);}else{n.nodeIndex=++ni;}n=nx;}this.isCleaned=true;return this;},calcOffsetsTo:function(el){el=Ext.get(el),d=el.dom;var _34=false;if(el.getStyle("position")=="static"){el.position("relative");_34=true;}var x=0,y=0;var op=this.dom;while(op&&op!=d&&op.tagName!="HTML"){x+=op.offsetLeft;y+=op.offsetTop;op=op.offsetParent;}if(_34){el.position("static");}return [x,y];},scrollIntoView:function(_38,_39){var c=Ext.getDom(_38)||document.body;var el=this.dom;var o=this.calcOffsetsTo(c),l=o[0],t=o[1],b=t+el.offsetHeight,r=l+el.offsetWidth;var ch=c.clientHeight;var ct=parseInt(c.scrollTop,10);var cl=parseInt(c.scrollLeft,10);var cb=ct+ch;var cr=cl+c.clientWidth;if(t<ct){c.scrollTop=t;}else{if(b>cb){c.scrollTop=b-ch;}}if(_39!==false){if(l<cl){c.scrollLeft=l;}else{if(r>cr){c.scrollLeft=r-c.clientWidth;}}}return this;},scrollChildIntoView:function(_46){Ext.fly(_46,"_scrollChildIntoView").scrollIntoView(this);},autoHeight:function(_47,_48,_49,_4a){var _4b=this.getHeight();this.clip();this.setHeight(1);setTimeout(function(){var _4c=parseInt(this.dom.scrollHeight,10);if(!_47){this.setHeight(_4c);this.unclip();if(typeof _49=="function"){_49();}}else{this.setHeight(_4b);this.setHeight(_4c,_47,_48,function(){this.unclip();if(typeof _49=="function"){_49();}}.createDelegate(this),_4a);}}.createDelegate(this),0);return this;},contains:function(el){if(!el){return false;}return D.isAncestor(this.dom,el.dom?el.dom:el);},isVisible:function(_4e){var vis=!(this.getStyle("visibility")=="hidden"||this.getStyle("display")=="none");if(_4e!==true||!vis){return vis;}var p=this.dom.parentNode;while(p&&p.tagName.toLowerCase()!="body"){if(!Ext.fly(p,"_isVisible").isVisible()){return false;}p=p.parentNode;}return true;},select:function(_51,_52){return El.select("#"+Ext.id(this.dom)+" "+_51,_52);},query:function(_53,_54){return Ext.DomQuery.select(_53,this.dom);},child:function(_55,_56){var n=Ext.DomQuery.selectNode(_55,this.dom);return _56?n:Ext.get(n);},initDD:function(_58,_59,_5a){var dd=new Ext.dd.DD(Ext.id(this.dom),_58,_59);return Ext.apply(dd,_5a);},initDDProxy:function(_5c,_5d,_5e){var dd=new Ext.dd.DDProxy(Ext.id(this.dom),_5c,_5d);return Ext.apply(dd,_5e);},initDDTarget:function(_60,_61,_62){var dd=new Ext.dd.DDTarget(Ext.id(this.dom),_60,_61);return Ext.apply(dd,_62);},setVisible:function(_64,_65){if(!_65||!A){if(this.visibilityMode==El.DISPLAY){this.setDisplayed(_64);}else{this.fixDisplay();this.dom.style.visibility=_64?"visible":"hidden";}}else{var dom=this.dom;var _67=this.visibilityMode;if(_64){this.setOpacity(0.01);this.setVisible(true);}this.anim({opacity:{to:(_64?1:0)}},this.preanim(arguments,1),null,0.35,"easeIn",function(){if(!_64){if(_67==El.DISPLAY){dom.style.display="none";}else{dom.style.visibility="hidden";}Ext.get(dom).setOpacity(1);}});}return this;},isDisplayed:function(){return this.getStyle("display")!="none";},toggle:function(_68){this.setVisible(!this.isVisible(),this.preanim(arguments,0));return this;},setDisplayed:function(_69){if(typeof _69=="boolean"){_69=_69?this.originalDisplay:"none";}this.setStyle("display",_69);return this;},focus:function(){try{this.dom.focus();}catch(e){}return this;},blur:function(){try{this.dom.blur();}catch(e){}return this;},addClass:function(_6a){if(_6a instanceof Array){for(var i=0,len=_6a.length;i<len;i++){this.addClass(_6a[i]);}}else{if(_6a&&!this.hasClass(_6a)){this.dom.className=this.dom.className+" "+_6a;}}return this;},radioClass:function(_6d){var _6e=this.dom.parentNode.childNodes;for(var i=0;i<_6e.length;i++){var s=_6e[i];if(s.nodeType==1){Ext.get(s).removeClass(_6d);}}this.addClass(_6d);return this;},removeClass:function(_71){if(!_71||!this.dom.className){return this;}if(_71 instanceof Array){for(var i=0,len=_71.length;i<len;i++){this.removeClass(_71[i]);}}else{if(this.hasClass(_71)){var re=this.classReCache[_71];if(!re){re=new RegExp("(?:^|\\s+)"+_71+"(?:\\s+|$)","g");this.classReCache[_71]=re;}this.dom.className=this.dom.className.replace(re," ");}}return this;},classReCache:{},toggleClass:function(_75){if(this.hasClass(_75)){this.removeClass(_75);}else{this.addClass(_75);}return this;},hasClass:function(_76){return _76&&(" "+this.dom.className+" ").indexOf(" "+_76+" ")!=-1;},replaceClass:function(_77,_78){this.removeClass(_77);this.addClass(_78);return this;},getStyles:function(){var a=arguments,len=a.length,r={};for(var i=0;i<len;i++){r[a[i]]=this.getStyle(a[i]);}return r;},getStyle:function(){return _9&&_9.getComputedStyle?function(_7d){var el=this.dom,v,cs,_81;if(_7d=="float"){_7d="cssFloat";}if(v=el.style[_7d]){return v;}if(cs=_9.getComputedStyle(el,"")){if(!(_81=_4[_7d])){_81=_4[_7d]=_7d.replace(_5,_6);}return cs[_81];}return null;}:function(_82){var el=this.dom,v,cs,_86;if(_82=="opacity"){if(typeof el.filter=="string"){var fv=parseFloat(el.filter.match(/alpha\(opacity=(.*)\)/i)[1]);if(!isNaN(fv)){return fv?fv/100:0;}}return 1;}else{if(_82=="float"){_82="styleFloat";}}if(!(_86=_4[_82])){_86=_4[_82]=_82.replace(_5,_6);}if(v=el.style[_86]){return v;}if(cs=el.currentStyle){return cs[_86];}return null;};}(),setStyle:function(_88,_89){if(typeof _88=="string"){var _8a;if(!(_8a=_4[_88])){_8a=_4[_88]=_88.replace(_5,_6);}if(_8a=="opacity"){this.setOpacity(_89);}else{this.dom.style[_8a]=_89;}}else{for(var _8b in _88){if(typeof _88[_8b]!="function"){this.setStyle(_8b,_88[_8b]);}}}return this;},applyStyles:function(_8c){Ext.DomHelper.applyStyles(this.dom,_8c);return this;},getX:function(){return D.getX(this.dom);},getY:function(){return D.getY(this.dom);},getXY:function(){return D.getXY(this.dom);},setX:function(x,_8e){if(!_8e||!A){D.setX(this.dom,x);}else{this.setXY([x,this.getY()],this.preanim(arguments,1));}return this;},setY:function(y,_90){if(!_90||!A){D.setY(this.dom,y);}else{this.setXY([this.getX(),y],this.preanim(arguments,1));}return this;},setLeft:function(_91){this.setStyle("left",this.addUnits(_91));return this;},setTop:function(top){this.setStyle("top",this.addUnits(top));return this;},setRight:function(_93){this.setStyle("right",this.addUnits(_93));return this;},setBottom:function(_94){this.setStyle("bottom",this.addUnits(_94));return this;},setXY:function(pos,_96){if(!_96||!A){D.setXY(this.dom,pos);}else{this.anim({points:{to:pos}},this.preanim(arguments,1),"motion");}return this;},setLocation:function(x,y,_99){this.setXY([x,y],this.preanim(arguments,2));return this;},moveTo:function(x,y,_9c){this.setXY([x,y],this.preanim(arguments,2));return this;},getRegion:function(){return D.getRegion(this.dom);},getHeight:function(_9d){var h=this.dom.offsetHeight||0;return _9d!==true?h:h-this.getBorderWidth("tb")-this.getPadding("tb");},getWidth:function(_9f){var w=this.dom.offsetWidth||0;return _9f!==true?w:w-this.getBorderWidth("lr")-this.getPadding("lr");},getComputedHeight:function(){var h=Math.max(this.dom.offsetHeight,this.dom.clientHeight);if(!h){h=parseInt(this.getStyle("height"),10)||0;if(!this.isBorderBox()){h+=this.getFrameWidth("tb");}}return h;},getComputedWidth:function(){var w=Math.max(this.dom.offsetWidth,this.dom.clientWidth);if(!w){w=parseInt(this.getStyle("width"),10)||0;if(!this.isBorderBox()){w+=this.getFrameWidth("lr");}}return w;},getSize:function(_a3){return {width:this.getWidth(_a3),height:this.getHeight(_a3)};},getValue:function(_a4){return _a4?parseInt(this.dom.value,10):this.dom.value;},adjustWidth:function(_a5){if(typeof _a5=="number"){if(this.autoBoxAdjust&&!this.isBorderBox()){_a5-=(this.getBorderWidth("lr")+this.getPadding("lr"));}if(_a5<0){_a5=0;}}return _a5;},adjustHeight:function(_a6){if(typeof _a6=="number"){if(this.autoBoxAdjust&&!this.isBorderBox()){_a6-=(this.getBorderWidth("tb")+this.getPadding("tb"));}if(_a6<0){_a6=0;}}return _a6;},setWidth:function(_a7,_a8){_a7=this.adjustWidth(_a7);if(!_a8||!A){this.dom.style.width=this.addUnits(_a7);}else{this.anim({width:{to:_a7}},this.preanim(arguments,1));}return this;},setHeight:function(_a9,_aa){_a9=this.adjustHeight(_a9);if(!_aa||!A){this.dom.style.height=this.addUnits(_a9);}else{this.anim({height:{to:_a9}},this.preanim(arguments,1));}return this;},setSize:function(_ab,_ac,_ad){if(typeof _ab=="object"){_ac=_ab.height;_ab=_ab.width;}_ab=this.adjustWidth(_ab);_ac=this.adjustHeight(_ac);if(!_ad||!A){this.dom.style.width=this.addUnits(_ab);this.dom.style.height=this.addUnits(_ac);}else{this.anim({width:{to:_ab},height:{to:_ac}},this.preanim(arguments,2));}return this;},setBounds:function(x,y,_b0,_b1,_b2){if(!_b2||!A){this.setSize(_b0,_b1);this.setLocation(x,y);}else{_b0=this.adjustWidth(_b0);_b1=this.adjustHeight(_b1);this.anim({points:{to:[x,y]},width:{to:_b0},height:{to:_b1}},this.preanim(arguments,4),"motion");}return this;},setRegion:function(_b3,_b4){this.setBounds(_b3.left,_b3.top,_b3.right-_b3.left,_b3.bottom-_b3.top,this.preanim(arguments,1));return this;},addListener:function(_b5,fn,_b7,_b8){Ext.EventManager.on(this.dom,_b5,fn,_b7||this,_b8);},removeListener:function(_b9,fn){Ext.EventManager.removeListener(this.dom,_b9,fn);return this;},removeAllListeners:function(){E.purgeElement(this.dom);return this;},relayEvent:function(_bb,_bc){this.on(_bb,function(e){_bc.fireEvent(_bb,e);});},setOpacity:function(_be,_bf){if(!_bf||!A){var s=this.dom.style;if(Ext.isIE){s.zoom=1;s.filter=(s.filter||"").replace(/alpha\([^\)]*\)/gi,"")+(_be==1?"":"alpha(opacity="+_be*100+")");}else{s.opacity=_be;}}else{this.anim({opacity:{to:_be}},this.preanim(arguments,1),null,0.35,"easeIn");}return this;},getLeft:function(_c1){if(!_c1){return this.getX();}else{return parseInt(this.getStyle("left"),10)||0;}},getRight:function(_c2){if(!_c2){return this.getX()+this.getWidth();}else{return (this.getLeft(true)+this.getWidth())||0;}},getTop:function(_c3){if(!_c3){return this.getY();}else{return parseInt(this.getStyle("top"),10)||0;}},getBottom:function(_c4){if(!_c4){return this.getY()+this.getHeight();}else{return (this.getTop(true)+this.getHeight())||0;}},position:function(pos,_c6,x,y){if(!pos){if(this.getStyle("position")=="static"){this.setStyle("position","relative");}}else{this.setStyle("position",pos);}if(_c6){this.setStyle("z-index",_c6);}if(x!==undefined&&y!==undefined){this.setXY([x,y]);}else{if(x!==undefined){this.setX(x);}else{if(y!==undefined){this.setY(y);}}}},clearPositioning:function(_c9){_c9=_c9||"";this.setStyle({"left":_c9,"right":_c9,"top":_c9,"bottom":_c9,"z-index":"","position":"static"});return this;},getPositioning:function(){var l=this.getStyle("left");var t=this.getStyle("top");return {"position":this.getStyle("position"),"left":l,"right":l?"":this.getStyle("right"),"top":t,"bottom":t?"":this.getStyle("bottom"),"z-index":this.getStyle("z-index")};},getBorderWidth:function(_cc){return this.addStyles(_cc,El.borders);},getPadding:function(_cd){return this.addStyles(_cd,El.paddings);},setPositioning:function(pc){this.applyStyles(pc);if(pc.right=="auto"){this.dom.style.right="";}if(pc.bottom=="auto"){this.dom.style.bottom="";}return this;},fixDisplay:function(){if(this.getStyle("display")=="none"){this.setStyle("visibility","hidden");this.setStyle("display",this.originalDisplay);if(this.getStyle("display")=="none"){this.setStyle("display","block");}}},setLeftTop:function(_cf,top){this.dom.style.left=this.addUnits(_cf);this.dom.style.top=this.addUnits(top);return this;},move:function(_d1,_d2,_d3){var xy=this.getXY();_d1=_d1.toLowerCase();switch(_d1){case "l":case "left":this.moveTo(xy[0]-_d2,xy[1],this.preanim(arguments,2));break;case "r":case "right":this.moveTo(xy[0]+_d2,xy[1],this.preanim(arguments,2));break;case "t":case "top":case "up":this.moveTo(xy[0],xy[1]-_d2,this.preanim(arguments,2));break;case "b":case "bottom":case "down":this.moveTo(xy[0],xy[1]+_d2,this.preanim(arguments,2));break;}return this;},clip:function(){if(!this.isClipped){this.isClipped=true;this.originalClip={"o":this.getStyle("overflow"),"x":this.getStyle("overflow-x"),"y":this.getStyle("overflow-y")};this.setStyle("overflow","hidden");this.setStyle("overflow-x","hidden");this.setStyle("overflow-y","hidden");}return this;},unclip:function(){if(this.isClipped){this.isClipped=false;var o=this.originalClip;if(o.o){this.setStyle("overflow",o.o);}if(o.x){this.setStyle("overflow-x",o.x);}if(o.y){this.setStyle("overflow-y",o.y);}}return this;},getAnchorXY:function(_d6,_d7,s){var w,h,vp=false;if(!s){var d=this.dom;if(d==document.body||d==document){vp=true;w=D.getViewWidth();h=D.getViewHeight();}else{w=this.getWidth();h=this.getHeight();}}else{w=s.width;h=s.height;}var x=0,y=0,r=Math.round;switch((_d6||"tl").toLowerCase()){case "c":x=r(w*0.5);y=r(h*0.5);break;case "t":x=r(w*0.5);y=0;break;case "l":x=0;y=r(h*0.5);break;case "r":x=w;y=r(h*0.5);break;case "b":x=r(w*0.5);y=h;break;case "tl":x=0;y=0;break;case "bl":x=0;y=h;break;case "br":x=w;y=h;break;case "tr":x=w;y=0;break;}if(_d7===true){return [x,y];}if(vp){var sc=this.getScroll();return [x+sc.left,y+sc.top];}var o=this.getXY();return [x+o[0],y+o[1]];},getAlignToXY:function(el,p,o){el=Ext.get(el),d=this.dom;if(!el.dom){throw "Element.alignTo with an element that doesn't exist";}var c=false;var p1="",p2="";o=o||[0,0];if(!p){p="tl-bl";}else{if(p=="?"){p="tl-bl?";}else{if(p.indexOf("-")==-1){p="tl-"+p;}}}p=p.toLowerCase();var m=p.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!m){throw "Element.alignTo with an invalid alignment "+p;}p1=m[1],p2=m[2],c=m[3]?true:false;var a1=this.getAnchorXY(p1,true);var a2=el.getAnchorXY(p2,false);var x=a2[0]-a1[0]+o[0];var y=a2[1]-a1[1]+o[1];if(c){var w=this.getWidth(),h=this.getHeight(),r=el.getRegion();var dw=D.getViewWidth()-5,dh=D.getViewHeight()-5;var p1y=p1.charAt(0),p1x=p1.charAt(p1.length-1);var p2y=p2.charAt(0),p2x=p2.charAt(p2.length-1);var _f6=((p1y=="t"&&p2y=="b")||(p1y=="b"&&p2y=="t"));var _f7=((p1x=="r"&&p2x=="l")||(p1x=="l"&&p2x=="r"));var doc=document;var _f9=(doc.documentElement.scrollLeft||doc.body.scrollLeft||0)+5;var _fa=(doc.documentElement.scrollTop||doc.body.scrollTop||0)+5;if((x+w)>dw){x=_f7?r.left-w:dw-w;}if(x<_f9){x=_f7?r.right:_f9;}if((y+h)>dh){y=_f6?r.top-h:dh-h;}if(y<_fa){y=_f6?r.bottom:_fa;}}return [x,y];},alignTo:function(_fb,_fc,_fd,_fe){var xy=this.getAlignToXY(_fb,_fc,_fd);this.setXY(xy,this.preanim(arguments,3));return this;},anchorTo:function(el,_101,_102,_103,_104,_105){var _106=function(){this.alignTo(el,_101,_102,_103);Ext.callback(_105,this);};Ext.EventManager.onWindowResize(_106,this);var tm=typeof _104;if(tm!="undefined"){Ext.EventManager.on(window,"scroll",_106,this,{buffer:tm=="number"?_104:50});}_106.call(this);return this;},clearOpacity:function(){if(window.ActiveXObject){this.dom.style.filter="";}else{this.dom.style.opacity="";this.dom.style["-moz-opacity"]="";this.dom.style["-khtml-opacity"]="";}return this;},hide:function(_108){this.setVisible(false,this.preanim(arguments,0));return this;},show:function(_109){this.setVisible(true,this.preanim(arguments,0));return this;},addUnits:function(size){return Ext.Element.addUnits(size,this.defaultUnit);},beginMeasure:function(){var el=this.dom;if(el.offsetWidth||el.offsetHeight){return this;}var _10c=[];var p=this.dom,b=document.body;while((!el.offsetWidth&&!el.offsetHeight)&&p&&p.tagName&&p!=b){var pe=Ext.get(p);if(pe.getStyle("display")=="none"){_10c.push({el:p,visibility:pe.getStyle("visibility")});p.style.visibility="hidden";p.style.display="block";}p=p.parentNode;}this._measureChanged=_10c;return this;},endMeasure:function(){var _110=this._measureChanged;if(_110){for(var i=0,len=_110.length;i<len;i++){var r=_110[i];r.el.style.visibility=r.visibility;r.el.style.display="none";}this._measureChanged=null;}return this;},update:function(html,_115,_116){if(typeof html=="undefined"){html="";}if(_115!==true){this.dom.innerHTML=html;if(typeof _116=="function"){_116();}return this;}var id=Ext.id();var dom=this.dom;html+="<span id=\""+id+"\"></span>";E.onAvailable(id,function(){var hd=document.getElementsByTagName("head")[0];var re=/(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/img;var _11b=/\ssrc=([\'\"])(.*?)\1/i;var _11c;while(_11c=re.exec(html)){var _11d=_11c[1]?_11c[1].match(_11b):false;if(_11d&&_11d[2]){var s=document.createElement("script");s.src=_11d[2];hd.appendChild(s);}else{if(_11c[2]&&_11c[2].length>0){eval(_11c[2]);}}}var el=document.getElementById(id);if(el){el.parentNode.removeChild(el);}if(typeof _116=="function"){_116();}});dom.innerHTML=html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/img,"");return this;},load:function(){var um=this.getUpdateManager();um.update.apply(um,arguments);return this;},getUpdateManager:function(){if(!this.updateManager){this.updateManager=new Ext.UpdateManager(this);}return this.updateManager;},unselectable:function(){this.dom.unselectable="on";this.swallowEvent("selectstart",true);this.applyStyles("-moz-user-select:none;-khtml-user-select:none;");this.addClass("x-unselectable");return this;},getCenterXY:function(){return this.getAlignToXY(document,"c-c");},center:function(_121){this.alignTo(_121||document,"c-c");return this;},isBorderBox:function(){return _122[this.dom.tagName.toLowerCase()]||Ext.isBorderBox;},getBox:function(_123,_124){var xy;if(!_124){xy=this.getXY();}else{var left=parseInt(this.getStyle("left"),10)||0;var top=parseInt(this.getStyle("top"),10)||0;xy=[left,top];}var el=this.dom,w=el.offsetWidth,h=el.offsetHeight,bx;if(!_123){bx={x:xy[0],y:xy[1],width:w,height:h};}else{var l=this.getBorderWidth("l")+this.getPadding("l");var r=this.getBorderWidth("r")+this.getPadding("r");var t=this.getBorderWidth("t")+this.getPadding("t");var b=this.getBorderWidth("b")+this.getPadding("b");bx={x:xy[0]+l,y:xy[1]+t,width:w-(l+r),height:h-(t+b)};}bx.right=bx.x+bx.width;bx.bottom=bx.y+bx.height;return bx;},getFrameWidth:function(_130){return this.getPadding(_130)+this.getBorderWidth(_130);},setBox:function(box,_132,_133){var w=box.width,h=box.height;if((_132&&!this.autoBoxAdjust)&&!this.isBorderBox()){w-=(this.getBorderWidth("lr")+this.getPadding("lr"));h-=(this.getBorderWidth("tb")+this.getPadding("tb"));}this.setBounds(box.x,box.y,w,h,this.preanim(arguments,2));return this;},repaint:function(){var dom=this.dom;this.addClass("x-repaint");setTimeout(function(){Ext.get(dom).removeClass("x-repaint");},1);return this;},getMargins:function(side){if(!side){return {top:parseInt(this.getStyle("margin-top"),10)||0,left:parseInt(this.getStyle("margin-left"),10)||0,bottom:parseInt(this.getStyle("margin-bottom"),10)||0,right:parseInt(this.getStyle("margin-right"),10)||0};}else{return this.addStyles(side,El.margins);}},addStyles:function(_138,_139){var val=0;for(var i=0,len=_138.length;i<len;i++){var w=parseInt(this.getStyle(_139[_138.charAt(i)]),10);if(!isNaN(w)){val+=w;}}return val;},createProxy:function(_13e,_13f,_140){if(_13f){_13f=Ext.getDom(_13f);}else{_13f=document.body;}_13e=typeof _13e=="object"?_13e:{tag:"div",cls:_13e};var _141=Ext.DomHelper.append(_13f,_13e,true);if(_140){_141.setBox(this.getBox());}return _141;},mask:function(msg,_143){if(this.getStyle("position")=="static"){this.setStyle("position","relative");}if(!this._mask){this._mask=Ext.DomHelper.append(this.dom,{tag:"div",cls:"ext-el-mask"},true);}this.addClass("x-masked");this._mask.setDisplayed(true);if(typeof msg=="string"){if(!this._maskMsg){this._maskMsg=Ext.DomHelper.append(this.dom,{tag:"div",cls:"ext-el-mask-msg",cn:{tag:"div"}},true);}var mm=this._maskMsg;mm.dom.className=_143?"ext-el-mask-msg "+_143:"ext-el-mask-msg";mm.dom.firstChild.innerHTML=msg;mm.setDisplayed(true);mm.center(this);}return this._mask;},unmask:function(_145){if(this._mask){if(_145===true){this._mask.remove();delete this._mask;if(this._maskMsg){this._maskMsg.remove();delete this._maskMsg;}}else{this._mask.setDisplayed(false);if(this._maskMsg){this._maskMsg.setDisplayed(false);}}}this.removeClass("x-masked");},isMasked:function(){return this._mask&&this._mask.isVisible();},createShim:function(){var _146={tag:"iframe",frameBorder:"no",cls:"yiframe-shim",style:"position:absolute;visibility:hidden;left:0;top:0;overflow:hidden;",src:Ext.SSL_SECURE_URL};var shim=Ext.DomHelper.insertBefore(this.dom,_146,true);shim.setOpacity(0.01);shim.setBox(this.getBox());return shim;},remove:function(){if(this.dom.parentNode){this.dom.parentNode.removeChild(this.dom);}delete El.cache[this.dom.id];},addClassOnOver:function(_148,_149){this.on("mouseover",function(){Ext.fly(this,"_internal").addClass(_148);},this.dom);var _14a=function(e){if(_149!==true||!e.within(this,true)){Ext.fly(this,"_internal").removeClass(_148);}};this.on("mouseout",_14a,this.dom);return this;},addClassOnFocus:function(_14c){this.on("focus",function(){Ext.fly(this,"_internal").addClass(_14c);},this.dom);this.on("blur",function(){Ext.fly(this,"_internal").removeClass(_14c);},this.dom);return this;},addClassOnClick:function(_14d){var dom=this.dom;this.on("mousedown",function(){Ext.fly(dom,"_internal").addClass(_14d);var d=Ext.get(document);var fn=function(){Ext.fly(dom,"_internal").removeClass(_14d);d.removeListener("mouseup",fn);};d.on("mouseup",fn);});return this;},swallowEvent:function(_151,_152){var fn=function(e){e.stopPropagation();if(_152){e.preventDefault();}};if(_151 instanceof Array){for(var i=0,len=_151.length;i<len;i++){this.on(_151[i],fn);}return this;}this.on(_151,fn);return this;},fitToParent:function(_157,_158){var p=Ext.get(_158||this.dom.parentNode);this.setSize(p.getComputedWidth()-p.getFrameWidth("lr"),p.getComputedHeight()-p.getFrameWidth("tb"));if(_157===true){Ext.EventManager.onWindowResize(this.fitToParent.createDelegate(this,[]));}return this;},getNextSibling:function(){var n=this.dom.nextSibling;while(n&&n.nodeType!=1){n=n.nextSibling;}return n;},getPrevSibling:function(){var n=this.dom.previousSibling;while(n&&n.nodeType!=1){n=n.previousSibling;}return n;},appendChild:function(el){el=Ext.get(el);el.appendTo(this);return this;},createChild:function(_15d,_15e,_15f){_15d=_15d||{tag:"div"};if(_15e){return Ext.DomHelper.insertBefore(_15e,_15d,_15f!==true);}return Ext.DomHelper.append(this.dom,_15d,_15f!==true);},appendTo:function(el){el=Ext.getDom(el);el.appendChild(this.dom);return this;},insertBefore:function(el){el=Ext.getDom(el);el.parentNode.insertBefore(this.dom,el);return this;},insertAfter:function(el){el=Ext.getDom(el);el.parentNode.insertBefore(this.dom,el.nextSibling);return this;},insertFirst:function(el,_164){el=el||{};if(typeof el=="object"&&!el.nodeType){return this.createChild(el,this.dom.firstChild,_164);}else{el=Ext.getDom(el);this.dom.insertBefore(el,this.dom.firstChild);return !_164?Ext.get(el):el;}},insertSibling:function(el,_166,_167){_166=_166?_166.toLowerCase():"before";el=el||{};var rt,_169=_166=="before"?this.dom:this.dom.nextSibling;if(typeof el=="object"&&!el.nodeType){if(_166=="after"&&!this.dom.nextSibling){rt=Ext.DomHelper.append(this.dom.parentNode,el,!_167);}else{rt=Ext.DomHelper[_166=="after"?"insertAfter":"insertBefore"](this.dom,el,!_167);}}else{rt=this.dom.parentNode.insertBefore(Ext.getDom(el),_166=="before"?this.dom:this.dom.nextSibling);if(!_167){rt=Ext.get(rt);}}return rt;},wrap:function(_16a,_16b){if(!_16a){_16a={tag:"div"};}var _16c=Ext.DomHelper.insertBefore(this.dom,_16a,!_16b);_16c.dom?_16c.dom.appendChild(this.dom):_16c.appendChild(this.dom);return _16c;},replace:function(el){el=Ext.get(el);this.insertBefore(el);el.remove();return this;},insertHtml:function(_16e,html){return Ext.DomHelper.insertHtml(_16e,this.dom,html);},set:function(o,_171){var el=this.dom;_171=typeof _171=="undefined"?(el.setAttribute?true:false):_171;for(var attr in o){if(attr=="style"||typeof o[attr]=="function"){continue;}if(attr=="cls"){el.className=o["cls"];}else{if(_171){el.setAttribute(attr,o[attr]);}else{el[attr]=o[attr];}}}Ext.DomHelper.applyStyles(el,o.style);return this;},addKeyListener:function(key,fn,_176){var _177;if(typeof key!="object"||key instanceof Array){_177={key:key,fn:fn,scope:_176};}else{_177={key:key.key,shift:key.shift,ctrl:key.ctrl,alt:key.alt,fn:fn,scope:_176};}return new Ext.KeyMap(this,_177);},addKeyMap:function(_178){return new Ext.KeyMap(this,_178);},isScrollable:function(){var dom=this.dom;return dom.scrollHeight>dom.clientHeight||dom.scrollWidth>dom.clientWidth;},scrollTo:function(side,_17b,_17c){var prop=side.toLowerCase()=="left"?"scrollLeft":"scrollTop";if(!_17c||!A){this.dom[prop]=_17b;}else{var to=prop=="scrollLeft"?[_17b,this.dom.scrollTop]:[this.dom.scrollLeft,_17b];this.anim({scroll:{"to":to}},this.preanim(arguments,2),"scroll");}return this;},scroll:function(_17f,_180,_181){if(!this.isScrollable()){return;}var el=this.dom;var l=el.scrollLeft,t=el.scrollTop;var w=el.scrollWidth,h=el.scrollHeight;var cw=el.clientWidth,ch=el.clientHeight;_17f=_17f.toLowerCase();var _189=false;var a=this.preanim(arguments,2);switch(_17f){case "l":case "left":if(w-l>cw){var v=Math.min(l+_180,w-cw);this.scrollTo("left",v,a);_189=true;}break;case "r":case "right":if(l>0){var v=Math.max(l-_180,0);this.scrollTo("left",v,a);_189=true;}break;case "t":case "top":case "up":if(t>0){var v=Math.max(t-_180,0);this.scrollTo("top",v,a);_189=true;}break;case "b":case "bottom":case "down":if(h-t>ch){var v=Math.min(t+_180,h-ch);this.scrollTo("top",v,a);_189=true;}break;}return _189;},translatePoints:function(x,y){if(typeof x=="object"||x instanceof Array){y=x[1];x=x[0];}var p=this.getStyle("position");var o=this.getXY();var l=parseInt(this.getStyle("left"),10);var t=parseInt(this.getStyle("top"),10);if(isNaN(l)){l=(p=="relative")?0:this.dom.offsetLeft;}if(isNaN(t)){t=(p=="relative")?0:this.dom.offsetTop;}return {left:(x-o[0]+l),top:(y-o[1]+t)};},getScroll:function(){var d=this.dom,doc=document;if(d==doc||d==doc.body){var l=window.pageXOffset||doc.documentElement.scrollLeft||doc.body.scrollLeft||0;var t=window.pageYOffset||doc.documentElement.scrollTop||doc.body.scrollTop||0;return {left:l,top:t};}else{return {left:d.scrollLeft,top:d.scrollTop};}},getColor:function(attr,_197,_198){var v=this.getStyle(attr);if(!v||v=="transparent"||v=="inherit"){return _197;}var _19a=typeof _198=="undefined"?"#":_198;if(v.substr(0,4)=="rgb("){var rvs=v.slice(4,v.length-1).split(",");for(var i=0;i<3;i++){var h=parseInt(rvs[i]).toString(16);if(h<16){h="0"+h;}_19a+=h;}}else{if(v.substr(0,1)=="#"){if(v.length==4){for(var i=1;i<4;i++){var c=v.charAt(i);_19a+=c+c;}}else{if(v.length==7){_19a+=v.substr(1);}}}}return (_19a.length>5?_19a.toLowerCase():_197);},boxWrap:function(cls){cls=cls||"x-box";var el=Ext.get(this.insertHtml("beforeBegin",String.format("<div class=\"{0}\"><div class=\"{0}-tl\"><div class=\"{0}-tr\"><div class=\"{0}-tc\"></div></div></div><div class=\"{0}-ml\"><div class=\"{0}-mr\"><div class=\"{0}-mc\"></div></div></div><div class=\"{0}-bl\"><div class=\"{0}-br\"><div class=\"{0}-bc\"></div></div></div></div>",cls)));el.child("."+cls+"-mc").dom.appendChild(this.dom);return el;},getAttributeNS:Ext.isIE?function(ns,name){var d=this.dom;var type=typeof d[ns+":"+name];if(type!="undefined"&&type!="unknown"){return d[ns+":"+name];}return d[name];}:function(ns,name){var d=this.dom;return d.getAttributeNS(ns,name)||d.getAttribute(ns+":"+name)||d.getAttribute(name)||d[name];}};var ep=El.prototype;ep.on=ep.addListener;ep.mon=ep.addListener;ep.un=ep.removeListener;ep.autoBoxAdjust=true;ep.autoDisplayMode=true;El.unitPattern=/\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i;El.addUnits=function(v,_1aa){if(v===""||v=="auto"){return v;}if(v===undefined){return "";}if(typeof v=="number"||!El.unitPattern.test(v)){return v+(_1aa||"px");}return v;};El.VISIBILITY=1;El.DISPLAY=2;El.borders={l:"border-left-width",r:"border-right-width",t:"border-top-width",b:"border-bottom-width"};El.paddings={l:"padding-left",r:"padding-right",t:"padding-top",b:"padding-bottom"};El.margins={l:"margin-left",r:"margin-right",t:"margin-top",b:"margin-bottom"};El.cache={};var _1ab;El.get=function(el){var ex,elm,id;if(!el){return null;}if(typeof el=="string"){if(!(elm=document.getElementById(el))){return null;}if(ex=El.cache[el]){ex.dom=elm;}else{ex=El.cache[el]=new El(elm);}return ex;}else{if(el.tagName){if(!(id=el.id)){id=Ext.id(el);}if(ex=El.cache[id]){ex.dom=el;}else{ex=El.cache[id]=new El(el);}return ex;}else{if(el instanceof El){if(el!=_1ab){el.dom=document.getElementById(el.id)||el.dom;El.cache[el.id]=el;}return el;}else{if(el.isComposite){return el;}else{if(el instanceof Array){return El.select(el);}else{if(el==document){if(!_1ab){var f=function(){};f.prototype=El.prototype;_1ab=new f();_1ab.dom=document;}return _1ab;}}}}}}return null;};El.Flyweight=function(dom){this.dom=dom;};El.Flyweight.prototype=El.prototype;El._flyweights={};El.fly=function(el,_1b3){_1b3=_1b3||"_global";el=Ext.getDom(el);if(!el){return null;}if(!El._flyweights[_1b3]){El._flyweights[_1b3]=new El.Flyweight();}El._flyweights[_1b3].dom=el;return El._flyweights[_1b3];};Ext.get=El.get;Ext.fly=El.fly;var _122=Ext.isStrict?{select:1}:{input:1,select:1,textarea:1};if(Ext.isIE||Ext.isGecko){_122["button"]=1;}})();
+
+Ext.enableFx=true;Ext.Fx={slideIn:function(_1,o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){_1=_1||"t";this.fixDisplay();var r=this.getFxRestore();var b=this.getBox();this.setSize(b);var _6=this.fxWrap(r.pos,o,"hidden");var st=this.dom.style;st.visibility="visible";st.position="absolute";var _8=function(){el.fxUnwrap(_6,r.pos,o);st.width=r.width;st.height=r.height;el.afterFx(o);};var a,pt={to:[b.x,b.y]},bw={to:b.width},bh={to:b.height};switch(_1.toLowerCase()){case "t":_6.setSize(b.width,0);st.left=st.bottom="0";a={height:bh};break;case "l":_6.setSize(0,b.height);st.right=st.top="0";a={width:bw};break;case "r":_6.setSize(0,b.height);_6.setX(b.right);st.left=st.top="0";a={width:bw,points:pt};break;case "b":_6.setSize(b.width,0);_6.setY(b.bottom);st.left=st.top="0";a={height:bh,points:pt};break;case "tl":_6.setSize(0,0);st.right=st.bottom="0";a={width:bw,height:bh};break;case "bl":_6.setSize(0,0);_6.setY(b.y+b.height);st.right=st.top="0";a={width:bw,height:bh,points:pt};break;case "br":_6.setSize(0,0);_6.setXY([b.right,b.bottom]);st.left=st.top="0";a={width:bw,height:bh,points:pt};break;case "tr":_6.setSize(0,0);_6.setX(b.x+b.width);st.left=st.bottom="0";a={width:bw,height:bh,points:pt};break;}this.dom.style.visibility="visible";_6.show();arguments.callee.anim=_6.fxanim(a,o,"motion",0.5,"easeOut",_8);});return this;},slideOut:function(_d,o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){_d=_d||"t";var r=this.getFxRestore();var b=this.getBox();this.setSize(b);var _12=this.fxWrap(r.pos,o,"visible");var st=this.dom.style;st.visibility="visible";st.position="absolute";_12.setSize(b);var _14=function(){if(o.useDisplay){el.setDisplayed(false);}else{el.hide();}el.fxUnwrap(_12,r.pos,o);st.width=r.width;st.height=r.height;el.afterFx(o);};var a,_16={to:0};switch(_d.toLowerCase()){case "t":st.left=st.bottom="0";a={height:_16};break;case "l":st.right=st.top="0";a={width:_16};break;case "r":st.left=st.top="0";a={width:_16,points:{to:[b.right,b.y]}};break;case "b":st.left=st.top="0";a={height:_16,points:{to:[b.x,b.bottom]}};break;case "tl":st.right=st.bottom="0";a={width:_16,height:_16};break;case "bl":st.right=st.top="0";a={width:_16,height:_16,points:{to:[b.x,b.bottom]}};break;case "br":st.left=st.top="0";a={width:_16,height:_16,points:{to:[b.x+b.width,b.bottom]}};break;case "tr":st.left=st.bottom="0";a={width:_16,height:_16,points:{to:[b.right,b.y]}};break;}arguments.callee.anim=_12.fxanim(a,o,"motion",0.5,"easeOut",_14);});return this;},puff:function(o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){this.clearOpacity();this.show();var r=this.getFxRestore();var st=this.dom.style;var _1b=function(){if(o.useDisplay){el.setDisplayed(false);}else{el.hide();}el.clearOpacity();el.setPositioning(r.pos);st.width=r.width;st.height=r.height;st.fontSize="";el.afterFx(o);};var _1c=this.getWidth();var _1d=this.getHeight();arguments.callee.anim=this.fxanim({width:{to:this.adjustWidth(_1c*2)},height:{to:this.adjustHeight(_1d*2)},points:{by:[-(_1c*0.5),-(_1d*0.5)]},opacity:{to:0},fontSize:{to:200,unit:"%"}},o,"motion",0.5,"easeOut",_1b);});return this;},switchOff:function(o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){this.clearOpacity();this.clip();var r=this.getFxRestore();var st=this.dom.style;var _22=function(){if(o.useDisplay){el.setDisplayed(false);}else{el.hide();}el.clearOpacity();el.setPositioning(r.pos);st.width=r.width;st.height=r.height;el.afterFx(o);};this.fxanim({opacity:{to:0.3}},null,null,0.1,null,function(){this.clearOpacity();(function(){this.fxanim({height:{to:1},points:{by:[0,this.getHeight()*0.5]}},o,"motion",0.3,"easeIn",_22);}).defer(100,this);});});return this;},highlight:function(_23,o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){_23=_23||"ffff9c";attr=o.attr||"backgroundColor";this.clearOpacity();this.show();var _26=this.getColor(attr);var _27=this.dom.style[attr];endColor=(o.endColor||_26)||"ffffff";var _28=function(){el.dom.style[attr]=_27;el.afterFx(o);};var a={};a[attr]={from:_23,to:endColor};arguments.callee.anim=this.fxanim(a,o,"color",1,"easeIn",_28);});return this;},frame:function(_2a,_2b,o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){_2a=_2a||"#C3DAF9";if(_2a.length==6){_2a="#"+_2a;}_2b=_2b||1;duration=o.duration||1;this.show();var b=this.getBox();var _2f=function(){var _30=this.createProxy({tag:"div",style:{visbility:"hidden",position:"absolute","z-index":"35000",border:"0px solid "+_2a}});var _31=Ext.isBorderBox?2:1;_30.animate({top:{from:b.y,to:b.y-20},left:{from:b.x,to:b.x-20},borderWidth:{from:0,to:10},opacity:{from:1,to:0},height:{from:b.height,to:(b.height+(20*_31))},width:{from:b.width,to:(b.width+(20*_31))}},duration,function(){_30.remove();});if(--_2b>0){_2f.defer((duration/2)*1000,this);}else{el.afterFx(o);}};_2f.call(this);});return this;},pause:function(_32){var el=this.getFxEl();var o={};el.queueFx(o,function(){setTimeout(function(){el.afterFx(o);},_32*1000);});return this;},fadeIn:function(o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){this.setOpacity(0);this.fixDisplay();this.dom.style.visibility="visible";var to=o.endOpacity||1;arguments.callee.anim=this.fxanim({opacity:{to:to}},o,null,0.5,"easeOut",function(){if(to==1){this.clearOpacity();}el.afterFx(o);});});return this;},fadeOut:function(o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){arguments.callee.anim=this.fxanim({opacity:{to:o.endOpacity||0}},o,null,0.5,"easeOut",function(){if(this.visibilityMode==Ext.Element.DISPLAY||o.useDisplay){this.dom.style.display="none";}else{this.dom.style.visibility="hidden";}this.clearOpacity();el.afterFx(o);});});return this;},scale:function(w,h,o){this.shift(Ext.apply({},o,{width:w,height:h}));return this;},shift:function(o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){var a={},w=o.width,h=o.height,x=o.x,y=o.y,op=o.opacity;if(w!==undefined){a.width={to:this.adjustWidth(w)};}if(h!==undefined){a.height={to:this.adjustHeight(h)};}if(x!==undefined||y!==undefined){a.points={to:[x!==undefined?x:this.getX(),y!==undefined?y:this.getY()]};}if(op!==undefined){a.opacity={to:op};}if(o.xy!==undefined){a.points={to:o.xy};}arguments.callee.anim=this.fxanim(a,o,"motion",0.35,"easeOut",function(){el.afterFx(o);});});return this;},ghost:function(_45,o){var el=this.getFxEl();o=o||{};el.queueFx(o,function(){_45=_45||"b";var r=this.getFxRestore();var w=this.getWidth(),h=this.getHeight();var st=this.dom.style;var _4c=function(){if(o.useDisplay){el.setDisplayed(false);}else{el.hide();}el.clearOpacity();el.setPositioning(r.pos);st.width=r.width;st.height=r.height;el.afterFx(o);};var a={opacity:{to:0},points:{}},pt=a.points;switch(_45.toLowerCase()){case "t":pt.by=[0,-h];break;case "l":pt.by=[-w,0];break;case "r":pt.by=[w,0];break;case "b":pt.by=[0,h];break;case "tl":pt.by=[-w,-h];break;case "bl":pt.by=[-w,h];break;case "br":pt.by=[w,h];break;case "tr":pt.by=[w,-h];break;}arguments.callee.anim=this.fxanim(a,o,"motion",0.5,"easeOut",_4c);});return this;},syncFx:function(){this.fxDefaults=Ext.apply(this.fxDefaults||{},{block:false,concurrent:true,stopFx:false});return this;},sequenceFx:function(){this.fxDefaults=Ext.apply(this.fxDefaults||{},{block:false,concurrent:false,stopFx:false});return this;},nextFx:function(){var ef=this.fxQueue[0];if(ef){ef.call(this);}},hasActiveFx:function(){return this.fxQueue&&this.fxQueue[0];},stopFx:function(){if(this.hasActiveFx()){var cur=this.fxQueue[0];if(cur&&cur.anim&&cur.anim.isAnimated()){this.fxQueue=[cur];cur.anim.stop(true);}}return this;},beforeFx:function(o){if(this.hasActiveFx()&&!o.concurrent){if(o.stopFx){this.stopFx();return true;}return false;}return true;},hasFxBlock:function(){var q=this.fxQueue;return q&&q[0]&&q[0].block;},queueFx:function(o,fn){if(!this.fxQueue){this.fxQueue=[];}if(!this.hasFxBlock()){Ext.applyIf(o,this.fxDefaults);if(!o.concurrent){var run=this.beforeFx(o);fn.block=o.block;this.fxQueue.push(fn);if(run){this.nextFx();}}else{fn.call(this);}}return this;},fxWrap:function(pos,o,vis){var _59;if(!o.wrap||!(_59=Ext.get(o.wrap))){var _5a;if(o.fixPosition){_5a=this.getXY();}var div=document.createElement("div");div.style.visibility=vis;_59=Ext.get(this.dom.parentNode.insertBefore(div,this.dom));_59.setPositioning(pos);if(_59.getStyle("position")=="static"){_59.position("relative");}this.clearPositioning("auto");_59.clip();_59.dom.appendChild(this.dom);if(_5a){_59.setXY(_5a);}}return _59;},fxUnwrap:function(_5c,pos,o){this.clearPositioning();this.setPositioning(pos);if(!o.wrap){_5c.dom.parentNode.insertBefore(this.dom,_5c.dom);_5c.remove();}},getFxRestore:function(){var st=this.dom.style;return {pos:this.getPositioning(),width:st.width,height:st.height};},afterFx:function(o){if(o.afterStyle){this.applyStyles(o.afterStyle);}if(o.remove===true){this.remove();}Ext.callback(o.callback,o.scope,[this]);if(!o.concurrent){this.fxQueue.shift();this.nextFx();}},getFxEl:function(){return Ext.get(this.dom);},fxanim:function(_61,opt,_63,_64,_65,cb){_63=_63||"run";opt=opt||{};var _67=Ext.lib.Anim[_63](this.dom,_61,(opt.duration||_64)||0.35,(opt.easing||_65)||"easeOut",function(){Ext.callback(cb,this);},this);opt.anim=_67;return _67;}};Ext.Fx.resize=Ext.Fx.scale;Ext.apply(Ext.Element.prototype,Ext.Fx);
+
+Ext.CompositeElement=function(_1){this.elements=[];this.addElements(_1);};Ext.CompositeElement.prototype={isComposite:true,addElements:function(_2){if(!_2){return this;}if(typeof _2=="string"){_2=Ext.Element.selectorFunction(_2);}var _3=this.elements;var _4=_3.length-1;for(var i=0,_6=_2.length;i<_6;i++){_3[++_4]=Ext.get(_2[i],true);}return this;},invoke:function(fn,_8){var _9=this.elements;for(var i=0,_b=_9.length;i<_b;i++){Ext.Element.prototype[fn].apply(_9[i],_8);}return this;},add:function(_c){if(typeof _c=="string"){this.addElements(Ext.Element.selectorFunction(_c));}else{if(_c.length!==undefined){this.addElements(_c);}else{this.addElements([_c]);}}return this;},each:function(fn,_e){var _f=this.elements;for(var i=0,len=_f.length;i<len;i++){if(fn.call(_e||_f[i],_f[i],this,i)===false){break;}}return this;},item:function(_12){return this.elements[_12];}};(function(){Ext.CompositeElement.createCall=function(_13,_14){if(!_13[_14]){_13[_14]=function(){return this.invoke(_14,arguments);};}};for(var _15 in Ext.Element.prototype){if(typeof Ext.Element.prototype[_15]=="function"){Ext.CompositeElement.createCall(Ext.CompositeElement.prototype,_15);}}})();Ext.CompositeElementLite=function(els){Ext.CompositeElementLite.superclass.constructor.call(this,els);var _17=function(){};_17.prototype=Ext.Element.prototype;this.el=new Ext.Element.Flyweight();};Ext.extend(Ext.CompositeElementLite,Ext.CompositeElement,{addElements:function(els){if(els){if(els instanceof Array){this.elements=this.elements.concat(els);}else{var _19=this.elements;var _1a=_19.length-1;for(var i=0,len=els.length;i<len;i++){_19[++_1a]=els[i];}}}return this;},invoke:function(fn,_1e){var els=this.elements;var el=this.el;for(var i=0,len=els.length;i<len;i++){el.dom=els[i];Ext.Element.prototype[fn].apply(el,_1e);}return this;},item:function(_23){this.el.dom=this.elements[_23];return this.el;},addListener:function(_24,_25,_26,opt){var els=this.elements;for(var i=0,len=els.length;i<len;i++){Ext.EventManager.on(els[i],_24,_25,_26||els[i],opt);}return this;},each:function(fn,_2c){var els=this.elements;var el=this.el;for(var i=0,len=els.length;i<len;i++){el.dom=els[i];if(fn.call(_2c||el,el,this,i)===false){break;}}return this;}});Ext.CompositeElementLite.prototype.on=Ext.CompositeElementLite.prototype.addListener;if(Ext.DomQuery){Ext.Element.selectorFunction=Ext.DomQuery.select;}Ext.Element.select=function(_31,_32){var els;if(typeof _31=="string"){els=Ext.Element.selectorFunction(_31);}else{if(_31.length!==undefined){els=_31;}else{throw "Invalid selector";}}if(_32===true){return new Ext.CompositeElement(els);}else{return new Ext.CompositeElementLite(els);}};Ext.select=Ext.Element.select;
+
+Ext.UpdateManager=function(el,_2){el=Ext.get(el);if(!_2&&el.updateManager){return el.updateManager;}this.el=el;this.defaultUrl=null;this.events={"beforeupdate":true,"update":true,"failure":true};var d=Ext.UpdateManager.defaults;this.sslBlankUrl=d.sslBlankUrl;this.disableCaching=d.disableCaching;this.indicatorText=d.indicatorText;this.showLoadIndicator=d.showLoadIndicator;this.timeout=d.timeout;this.loadScripts=d.loadScripts;this.transaction=null;this.autoRefreshProcId=null;this.refreshDelegate=this.refresh.createDelegate(this);this.updateDelegate=this.update.createDelegate(this);this.formUpdateDelegate=this.formUpdate.createDelegate(this);this.successDelegate=this.processSuccess.createDelegate(this);this.failureDelegate=this.processFailure.createDelegate(this);this.renderer=new Ext.UpdateManager.BasicRenderer();Ext.UpdateManager.superclass.constructor.call(this);};Ext.extend(Ext.UpdateManager,Ext.util.Observable,{getEl:function(){return this.el;},update:function(_4,_5,_6,_7){if(this.fireEvent("beforeupdate",this.el,_4,_5)!==false){var _8=this.method;if(typeof _4=="object"){var _9=_4;_4=_9.url;_5=_5||_9.params;_6=_6||_9.callback;_7=_7||_9.discardUrl;if(_6&&_9.scope){_6=_6.createDelegate(_9.scope);}if(typeof _9.method!="undefined"){_8=_9.method;}if(typeof _9.nocache!="undefined"){this.disableCaching=_9.nocache;}if(typeof _9.text!="undefined"){this.indicatorText="<div class=\"loading-indicator\">"+_9.text+"</div>";}if(typeof _9.scripts!="undefined"){this.loadScripts=_9.scripts;}if(typeof _9.timeout!="undefined"){this.timeout=_9.timeout;}}this.showLoading();if(!_7){this.defaultUrl=_4;}if(typeof _4=="function"){_4=_4.call(this);}if(typeof _5=="function"){_5=_5();}if(_5&&typeof _5!="string"){var _a=[];for(var _b in _5){if(typeof _5[_b]!="function"){_a.push(encodeURIComponent(_b),"=",encodeURIComponent(_5[_b]),"&");}}delete _a[_a.length-1];_5=_a.join("");}var cb={success:this.successDelegate,failure:this.failureDelegate,timeout:(this.timeout*1000),argument:{"url":_4,"form":null,"callback":_6,"params":_5}};_8=_8||(_5?"POST":"GET");if(_8=="GET"){_4=this.prepareUrl(_4);}this.transaction=Ext.lib.Ajax.request(_8,_4,cb,_5);}},formUpdate:function(_d,_e,_f,_10){if(this.fireEvent("beforeupdate",this.el,_d,_e)!==false){formEl=Ext.getDom(_d);if(typeof _e=="function"){_e=_e.call(this);}if(typeof params=="function"){params=params();}_e=_e||formEl.action;var cb={success:this.successDelegate,failure:this.failureDelegate,timeout:(this.timeout*1000),argument:{"url":_e,"form":formEl,"callback":_10,"reset":_f}};var _12=false;var _13=formEl.getAttribute("enctype");if(_13&&_13.toLowerCase()=="multipart/form-data"){_12=true;cb.upload=this.successDelegate;}this.transaction=Ext.lib.Ajax.formRequest(formEl,_e,cb,null,_12,this.sslBlankUrl);this.showLoading.defer(1,this);}},refresh:function(_14){if(this.defaultUrl==null){return;}this.update(this.defaultUrl,null,_14,true);},startAutoRefresh:function(_15,url,_17,_18,_19){if(_19){this.update(url||this.defaultUrl,_17,_18,true);}if(this.autoRefreshProcId){clearInterval(this.autoRefreshProcId);}this.autoRefreshProcId=setInterval(this.update.createDelegate(this,[url||this.defaultUrl,_17,_18,true]),_15*1000);},stopAutoRefresh:function(){if(this.autoRefreshProcId){clearInterval(this.autoRefreshProcId);delete this.autoRefreshProcId;}},isAutoRefreshing:function(){return this.autoRefreshProcId?true:false;},showLoading:function(){if(this.showLoadIndicator){this.el.update(this.indicatorText);}},prepareUrl:function(url){if(this.disableCaching){var _1b="_dc="+(new Date().getTime());if(url.indexOf("?")!==-1){url+="&"+_1b;}else{url+="?"+_1b;}}return url;},processSuccess:function(_1c){this.transaction=null;if(_1c.argument.form&&_1c.argument.reset){try{_1c.argument.form.reset();}catch(e){}}if(this.loadScripts){this.renderer.render(this.el,_1c,this,this.updateComplete.createDelegate(this,[_1c]));}else{this.renderer.render(this.el,_1c,this);this.updateComplete(_1c);}},updateComplete:function(_1d){this.fireEvent("update",this.el,_1d);if(typeof _1d.argument.callback=="function"){_1d.argument.callback(this.el,true,_1d);}},processFailure:function(_1e){this.transaction=null;this.fireEvent("failure",this.el,_1e);if(typeof _1e.argument.callback=="function"){_1e.argument.callback(this.el,false,_1e);}},setRenderer:function(_1f){this.renderer=_1f;},getRenderer:function(){return this.renderer;},setDefaultUrl:function(_20){this.defaultUrl=_20;},abort:function(){if(this.transaction){Ext.lib.Ajax.abort(this.transaction);}},isUpdating:function(){if(this.transaction){return Ext.lib.Ajax.isCallInProgress(this.transaction);}return false;}});Ext.UpdateManager.defaults={timeout:30,loadScripts:false,sslBlankUrl:(Ext.SSL_SECURE_URL||"javascript:false"),disableCaching:false,showLoadIndicator:true,indicatorText:"<div class=\"loading-indicator\">Loading...</div>"};Ext.UpdateManager.updateElement=function(el,url,_23,_24){var um=Ext.get(el,true).getUpdateManager();Ext.apply(um,_24);um.update(url,_23,_24?_24.callback:null);};Ext.UpdateManager.update=Ext.UpdateManager.updateElement;Ext.UpdateManager.BasicRenderer=function(){};Ext.UpdateManager.BasicRenderer.prototype={render:function(el,_27,_28,_29){el.update(_27.responseText,_28.loadScripts,_29);}};
+
+Date.parseFunctions={count:0};Date.parseRegexes=[];Date.formatFunctions={count:0};Date.prototype.dateFormat=function(_1){if(Date.formatFunctions[_1]==null){Date.createNewFormat(_1);}var _2=Date.formatFunctions[_1];return this[_2]();};Date.prototype.format=Date.prototype.dateFormat;Date.createNewFormat=function(_3){var _4="format"+Date.formatFunctions.count++;Date.formatFunctions[_3]=_4;var _5="Date.prototype."+_4+" = function(){return ";var _6=false;var ch="";for(var i=0;i<_3.length;++i){ch=_3.charAt(i);if(!_6&&ch=="\\"){_6=true;}else{if(_6){_6=false;_5+="'"+String.escape(ch)+"' + ";}else{_5+=Date.getFormatCode(ch);}}}eval(_5.substring(0,_5.length-3)+";}");};Date.getFormatCode=function(_9){switch(_9){case "d":return "String.leftPad(this.getDate(), 2, '0') + ";case "D":return "Date.dayNames[this.getDay()].substring(0, 3) + ";case "j":return "this.getDate() + ";case "l":return "Date.dayNames[this.getDay()] + ";case "S":return "this.getSuffix() + ";case "w":return "this.getDay() + ";case "z":return "this.getDayOfYear() + ";case "W":return "this.getWeekOfYear() + ";case "F":return "Date.monthNames[this.getMonth()] + ";case "m":return "String.leftPad(this.getMonth() + 1, 2, '0') + ";case "M":return "Date.monthNames[this.getMonth()].substring(0, 3) + ";case "n":return "(this.getMonth() + 1) + ";case "t":return "this.getDaysInMonth() + ";case "L":return "(this.isLeapYear() ? 1 : 0) + ";case "Y":return "this.getFullYear() + ";case "y":return "('' + this.getFullYear()).substring(2, 4) + ";case "a":return "(this.getHours() < 12 ? 'am' : 'pm') + ";case "A":return "(this.getHours() < 12 ? 'AM' : 'PM') + ";case "g":return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";case "G":return "this.getHours() + ";case "h":return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";case "H":return "String.leftPad(this.getHours(), 2, '0') + ";case "i":return "String.leftPad(this.getMinutes(), 2, '0') + ";case "s":return "String.leftPad(this.getSeconds(), 2, '0') + ";case "O":return "this.getGMTOffset() + ";case "T":return "this.getTimezone() + ";case "Z":return "(this.getTimezoneOffset() * -60) + ";default:return "'"+String.escape(_9)+"' + ";}};Date.parseDate=function(_a,_b){if(Date.parseFunctions[_b]==null){Date.createParser(_b);}var _c=Date.parseFunctions[_b];return Date[_c](_a);};Date.createParser=function(_d){var _e="parse"+Date.parseFunctions.count++;var _f=Date.parseRegexes.length;var _10=1;Date.parseFunctions[_d]=_e;var _11="Date."+_e+" = function(input){\n"+"var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n"+"var d = new Date();\n"+"y = d.getFullYear();\n"+"m = d.getMonth();\n"+"d = d.getDate();\n"+"var results = input.match(Date.parseRegexes["+_f+"]);\n"+"if (results && results.length > 0) {";var _12="";var _13=false;var ch="";for(var i=0;i<_d.length;++i){ch=_d.charAt(i);if(!_13&&ch=="\\"){_13=true;}else{if(_13){_13=false;_12+=String.escape(ch);}else{var obj=Date.formatCodeToRegex(ch,_10);_10+=obj.g;_12+=obj.s;if(obj.g&&obj.c){_11+=obj.c;}}}}_11+="if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"+"{return new Date(y, m, d, h, i, s);}\n"+"else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"+"{return new Date(y, m, d, h, i);}\n"+"else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"+"{return new Date(y, m, d, h);}\n"+"else if (y > 0 && m >= 0 && d > 0)\n"+"{return new Date(y, m, d);}\n"+"else if (y > 0 && m >= 0)\n"+"{return new Date(y, m);}\n"+"else if (y > 0)\n"+"{return new Date(y);}\n"+"}return null;}";Date.parseRegexes[_f]=new RegExp("^"+_12+"$");eval(_11);};Date.formatCodeToRegex=function(_17,_18){switch(_17){case "D":return {g:0,c:null,s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};case "j":case "d":return {g:1,c:"d = parseInt(results["+_18+"], 10);\n",s:"(\\d{1,2})"};case "l":return {g:0,c:null,s:"(?:"+Date.dayNames.join("|")+")"};case "S":return {g:0,c:null,s:"(?:st|nd|rd|th)"};case "w":return {g:0,c:null,s:"\\d"};case "z":return {g:0,c:null,s:"(?:\\d{1,3})"};case "W":return {g:0,c:null,s:"(?:\\d{2})"};case "F":return {g:1,c:"m = parseInt(Date.monthNumbers[results["+_18+"].substring(0, 3)], 10);\n",s:"("+Date.monthNames.join("|")+")"};case "M":return {g:1,c:"m = parseInt(Date.monthNumbers[results["+_18+"]], 10);\n",s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};case "n":case "m":return {g:1,c:"m = parseInt(results["+_18+"], 10) - 1;\n",s:"(\\d{1,2})"};case "t":return {g:0,c:null,s:"\\d{1,2}"};case "L":return {g:0,c:null,s:"(?:1|0)"};case "Y":return {g:1,c:"y = parseInt(results["+_18+"], 10);\n",s:"(\\d{4})"};case "y":return {g:1,c:"var ty = parseInt(results["+_18+"], 10);\n"+"y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"};case "a":return {g:1,c:"if (results["+_18+"] == 'am') {\n"+"if (h == 12) { h = 0; }\n"+"} else { if (h < 12) { h += 12; }}",s:"(am|pm)"};case "A":return {g:1,c:"if (results["+_18+"] == 'AM') {\n"+"if (h == 12) { h = 0; }\n"+"} else { if (h < 12) { h += 12; }}",s:"(AM|PM)"};case "g":case "G":case "h":case "H":return {g:1,c:"h = parseInt(results["+_18+"], 10);\n",s:"(\\d{1,2})"};case "i":return {g:1,c:"i = parseInt(results["+_18+"], 10);\n",s:"(\\d{2})"};case "s":return {g:1,c:"s = parseInt(results["+_18+"], 10);\n",s:"(\\d{2})"};case "O":return {g:0,c:null,s:"[+-]\\d{4}"};case "T":return {g:0,c:null,s:"[A-Z]{3}"};case "Z":return {g:0,c:null,s:"[+-]\\d{1,5}"};default:return {g:0,c:null,s:String.escape(_17)};}};Date.prototype.getTimezone=function(){return this.toString().replace(/^.*? ([A-Z]{3}) [0-9]{4}.*$/,"$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/,"$1$2$3");};Date.prototype.getGMTOffset=function(){return (this.getTimezoneOffset()>0?"-":"+")+String.leftPad(Math.floor(this.getTimezoneOffset()/60),2,"0")+String.leftPad(this.getTimezoneOffset()%60,2,"0");};Date.prototype.getDayOfYear=function(){var num=0;Date.daysInMonth[1]=this.isLeapYear()?29:28;for(var i=0;i<this.getMonth();++i){num+=Date.daysInMonth[i];}return num+this.getDate()-1;};Date.prototype.getWeekOfYear=function(){var now=this.getDayOfYear()+(4-this.getDay());var _1c=new Date(this.getFullYear(),0,1);var _1d=(7-_1c.getDay()+4);return String.leftPad(((now-_1d)/7)+1,2,"0");};Date.prototype.isLeapYear=function(){var _1e=this.getFullYear();return ((_1e&3)==0&&(_1e%100||(_1e%400==0&&_1e)));};Date.prototype.getFirstDayOfMonth=function(){var day=(this.getDay()-(this.getDate()-1))%7;return (day<0)?(day+7):day;};Date.prototype.getLastDayOfMonth=function(){var day=(this.getDay()+(Date.daysInMonth[this.getMonth()]-this.getDate()))%7;return (day<0)?(day+7):day;};Date.prototype.getFirstDateOfMonth=function(){return new Date(this.getFullYear(),this.getMonth(),1);};Date.prototype.getLastDateOfMonth=function(){return new Date(this.getFullYear(),this.getMonth(),this.getDaysInMonth());};Date.prototype.getDaysInMonth=function(){Date.daysInMonth[1]=this.isLeapYear()?29:28;return Date.daysInMonth[this.getMonth()];};Date.prototype.getSuffix=function(){switch(this.getDate()){case 1:case 21:case 31:return "st";case 2:case 22:return "nd";case 3:case 23:return "rd";default:return "th";}};Date.daysInMonth=[31,28,31,30,31,30,31,31,30,31,30,31];Date.monthNames=["January","February","March","April","May","June","July","August","September","October","November","December"];Date.dayNames=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];Date.y2kYear=50;Date.monthNumbers={Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.clearTime=function(_21){if(_21){return this.clone().clearTime();}this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};if(Ext.isSafari){Date.brokenSetMonth=Date.prototype.setMonth;Date.prototype.setMonth=function(num){if(num<=-1){var n=Math.ceil(-num);var _24=Math.ceil(n/12);var _25=(n%12)?12-n%12:0;this.setFullYear(this.getFullYear()-_24);return Date.brokenSetMonth.call(this,_25);}else{return Date.brokenSetMonth.apply(this,arguments);}};}Date.MILLI="ms";Date.SECOND="s";Date.MINUTE="mi";Date.HOUR="h";Date.DAY="d";Date.MONTH="mo";Date.YEAR="y";Date.prototype.add=function(_26,_27){var d=this.clone();if(!_26||_27===0){return d;}switch(_26.toLowerCase()){case Date.MILLI:d.setMilliseconds(this.getMilliseconds()+_27);break;case Date.SECOND:d.setSeconds(this.getSeconds()+_27);break;case Date.MINUTE:d.setMinutes(this.getMinutes()+_27);break;case Date.HOUR:d.setHours(this.getHours()+_27);break;case Date.DAY:d.setDate(this.getDate()+_27);break;case Date.MONTH:var day=this.getDate();if(day>28){day=Math.min(day,this.getFirstDateOfMonth().add("mo",_27).getLastDateOfMonth().getDate());}d.setDate(day);d.setMonth(this.getMonth()+_27);break;case Date.YEAR:d.setFullYear(this.getFullYear()+_27);break;}return d;};
+
+Ext.util.DelayedTask=function(fn,_2,_3){var id=null,d,t;var _7=function(){var _8=new Date().getTime();if(_8-t>=d){clearInterval(id);id=null;fn.apply(_2,_3||[]);}};this.delay=function(_9,_a,_b,_c){if(id&&_9!=d){this.cancel();}d=_9;t=new Date().getTime();fn=_a||fn;_2=_b||_2;_3=_c||_3;if(!id){id=setInterval(_7,d);}};this.cancel=function(){if(id){clearInterval(id);id=null;}};};
+
+Ext.util.TaskRunner=function(_1){_1=_1||10;var _2=[],_3=[];var id=0;var _5=false;var _6=function(){_5=false;clearInterval(id);id=0;};var _7=function(){if(!_5){_5=true;id=setInterval(_8,_1);}};var _9=function(_a){_3.push(_a);if(_a.onStop){_a.onStop();}};var _8=function(){if(_3.length>0){for(var i=0,_c=_3.length;i<_c;i++){_2.remove(_3[i]);}_3=[];if(_2.length<1){_6();return;}}var _d=new Date().getTime();for(var i=0,_c=_2.length;i<_c;++i){var t=_2[i];var _f=_d-t.taskRunTime;if(t.interval<=_f){var rt=t.run.apply(t.scope||t,t.args||[++t.taskRunCount]);t.taskRunTime=_d;if(rt===false||t.taskRunCount===t.repeat){_9(t);return;}}if(t.duration&&t.duration<=(_d-t.taskStartTime)){_9(t);}}};this.start=function(_11){_2.push(_11);_11.taskStartTime=new Date().getTime();_11.taskRunTime=0;_11.taskRunCount=0;_7();return _11;};this.stop=function(_12){_9(_12);return _12;};this.stopAll=function(){_6();for(var i=0,len=_2.length;i<len;i++){if(_2[i].onStop){_2[i].onStop();}}_2=[];_3=[];};};Ext.TaskMgr=new Ext.util.TaskRunner();
+
+Ext.util.MixedCollection=function(_1,_2){this.items=[];this.map={};this.keys=[];this.length=0;this.events={"clear":true,"add":true,"replace":true,"remove":true,"sort":true};this.allowFunctions=_1===true;if(_2){this.getKey=_2;}Ext.util.MixedCollection.superclass.constructor.call(this);};Ext.extend(Ext.util.MixedCollection,Ext.util.Observable,{allowFunctions:false,add:function(_3,o){if(arguments.length==1){o=arguments[0];_3=this.getKey(o);}if(typeof _3=="undefined"||_3===null){this.length++;this.items.push(o);this.keys.push(null);}else{var _5=this.map[_3];if(_5){return this.replace(_3,o);}this.length++;this.items.push(o);this.map[_3]=o;this.keys.push(_3);}this.fireEvent("add",this.length-1,o,_3);return o;},getKey:function(o){return o.id;},replace:function(_7,o){if(arguments.length==1){o=arguments[0];_7=this.getKey(o);}var _9=this.item(_7);if(typeof _7=="undefined"||_7===null||typeof _9=="undefined"){return this.add(_7,o);}var _a=this.indexOfKey(_7);this.items[_a]=o;this.map[_7]=o;this.fireEvent("replace",_7,_9,o);return o;},addAll:function(_b){if(arguments.length>1||_b instanceof Array){var _c=arguments.length>1?arguments:_b;for(var i=0,_e=_c.length;i<_e;i++){this.add(_c[i]);}}else{for(var _f in _b){if(this.allowFunctions||typeof _b[_f]!="function"){this.add(_b[_f],_f);}}}},each:function(fn,_11){var _12=[].concat(this.items);for(var i=0,len=_12.length;i<len;i++){if(fn.call(_11||_12[i],_12[i],i,len)===false){break;}}},eachKey:function(fn,_16){for(var i=0,len=this.keys.length;i<len;i++){fn.call(_16||window,this.keys[i],this.items[i],i,len);}},find:function(fn,_1a){for(var i=0,len=this.items.length;i<len;i++){if(fn.call(_1a||window,this.items[i],this.keys[i])){return this.items[i];}}return null;},insert:function(_1d,key,o){if(arguments.length==2){o=arguments[1];key=this.getKey(o);}if(_1d>=this.length){return this.add(key,o);}this.length++;this.items.splice(_1d,0,o);if(typeof key!="undefined"&&key!=null){this.map[key]=o;}this.keys.splice(_1d,0,key);this.fireEvent("add",_1d,o,key);return o;},remove:function(o){return this.removeAt(this.indexOf(o));},removeAt:function(_21){if(_21<this.length&&_21>=0){this.length--;var o=this.items[_21];this.items.splice(_21,1);var key=this.keys[_21];if(typeof key!="undefined"){delete this.map[key];}this.keys.splice(_21,1);this.fireEvent("remove",o,key);}},removeKey:function(key){return this.removeAt(this.indexOfKey(key));},getCount:function(){return this.length;},indexOf:function(o){if(!this.items.indexOf){for(var i=0,len=this.items.length;i<len;i++){if(this.items[i]==o){return i;}}return -1;}else{return this.items.indexOf(o);}},indexOfKey:function(key){if(!this.keys.indexOf){for(var i=0,len=this.keys.length;i<len;i++){if(this.keys[i]==key){return i;}}return -1;}else{return this.keys.indexOf(key);}},item:function(key){var _2c=typeof this.map[key]!="undefined"?this.map[key]:this.items[key];return typeof _2c!="function"||this.allowFunctions?_2c:null;},itemAt:function(_2d){return this.items[_2d];},key:function(key){return this.map[key];},contains:function(o){return this.indexOf(o)!=-1;},containsKey:function(key){return typeof this.map[key]!="undefined";},clear:function(){this.length=0;this.items=[];this.keys=[];this.map={};this.fireEvent("clear");},first:function(){return this.items[0];},last:function(){return this.items[this.length-1];},_sort:function(_31,dir,fn){var dsc=String(dir).toUpperCase()=="DESC"?-1:1;fn=fn||function(a,b){return a-b;};var c=[],k=this.keys,_39=this.items;for(var i=0,len=_39.length;i<len;i++){c[c.length]={key:k[i],value:_39[i],index:i};}c.sort(function(a,b){var v=fn(a[_31],b[_31])*dsc;if(v==0){v=(a.index<b.index?-1:1);}return v;});for(var i=0,len=c.length;i<len;i++){_39[i]=c[i].value;k[i]=c[i].key;}this.fireEvent("sort",this);},sort:function(dir,fn){this._sort("value",dir,fn);},keySort:function(dir,fn){this._sort("key",dir,fn||function(a,b){return String(a).toUpperCase()-String(b).toUpperCase();});},getRange:function(_45,end){var _47=this.items;if(_47.length<1){return [];}_45=_45||0;end=Math.min(typeof end=="undefined"?this.length-1:end,this.length-1);var r=[];if(_45<=end){for(var i=_45;i<=end;i++){r[r.length]=_47[i];}}else{for(var i=_45;i>=end;i--){r[r.length]=_47[i];}}return r;},filter:function(_4a,_4b){if(!_4b.exec){_4b=String(_4b);if(_4b.length==0){return this.clone();}_4b=new RegExp("^"+Ext.escapeRe(_4b),"i");}return this.filterBy(function(o){return o&&_4b.test(o[_4a]);});},filterBy:function(fn,_4e){var r=new Ext.util.MixedCollection();r.getKey=this.getKey;var k=this.keys,it=this.items;for(var i=0,len=it.length;i<len;i++){if(fn.call(_4e||this,it[i],k[i])){r.add(k[i],it[i]);}}return r;},clone:function(){var r=new Ext.util.MixedCollection();var k=this.keys,it=this.items;for(var i=0,len=it.length;i<len;i++){r.add(k[i],it[i]);}r.getKey=this.getKey;return r;}});Ext.util.MixedCollection.prototype.get=Ext.util.MixedCollection.prototype.item;
+
+Ext.util.JSON=new (function(){var _1={}.hasOwnProperty?true:false;var _2=function(n){return n<10?"0"+n:n;};var m={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\"":"\\\"","\\":"\\\\"};var _5=function(s){if(/["\\\x00-\x1f]/.test(s)){return "\""+s.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;}c=b.charCodeAt();return "\\u00"+Math.floor(c/16).toString(16)+(c%16).toString(16);})+"\"";}return "\""+s+"\"";};var _a=function(o){var a=["["],b,i,l=o.length,v;for(i=0;i<l;i+=1){v=o[i];switch(typeof v){case "undefined":case "function":case "unknown":break;default:if(b){a.push(",");}a.push(v===null?"null":Ext.util.JSON.encode(v));b=true;}}a.push("]");return a.join("");};var _11=function(o){return "\""+o.getFullYear()+"-"+_2(o.getMonth()+1)+"-"+_2(o.getDate())+"T"+_2(o.getHours())+":"+_2(o.getMinutes())+":"+_2(o.getSeconds())+"\"";};this.encode=function(o){if(typeof o=="undefined"||o===null){return "null";}else{if(o instanceof Array){return _a(o);}else{if(o instanceof Date){return _11(o);}else{if(typeof o=="string"){return _5(o);}else{if(typeof o=="number"){return isFinite(o)?String(o):"null";}else{if(typeof o=="boolean"){return String(o);}else{var a=["{"],b,i,v;for(i in o){if(!_1||o.hasOwnProperty(i)){v=o[i];switch(typeof v){case "undefined":case "function":case "unknown":break;default:if(b){a.push(",");}a.push(this.encode(i),":",v===null?"null":this.encode(v));b=true;}}}a.push("}");return a.join("");}}}}}}};this.decode=function(_18){return eval("("+_18+")");};})();Ext.encode=Ext.util.JSON.encode;Ext.decode=Ext.util.JSON.decode;
+
+Ext.util.Format=function(){var _1=/^\s+|\s+$/g;return {ellipsis:function(_2,_3){if(_2&&_2.length>_3){return _2.substr(0,_3-3)+"...";}return _2;},undef:function(_4){return typeof _4!="undefined"?_4:"";},htmlEncode:function(_5){return !_5?_5:String(_5).replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;");},trim:function(_6){return String(_6).replace(_1,"");},substr:function(_7,_8,_9){return String(_7).substr(_8,_9);},lowercase:function(_a){return String(_a).toLowerCase();},uppercase:function(_b){return String(_b).toUpperCase();},capitalize:function(_c){return !_c?_c:_c.charAt(0).toUpperCase()+_c.substr(1).toLowerCase();},call:function(_d,fn){if(arguments.length>2){var _f=Array.prototype.slice.call(arguments,2);_f.unshift(_d);return eval(fn).apply(window,_f);}else{return eval(fn).call(window,_d);}},usMoney:function(v){v=(Math.round((v-0)*100))/100;v=(v==Math.floor(v))?v+".00":((v*10==Math.floor(v*10))?v+"0":v);return "$"+v;},date:function(v,_12){if(!v){return "";}if(!(v instanceof Date)){v=new Date(Date.parse(v));}return v.dateFormat(_12||"m/d/Y");},dateRenderer:function(_13){return function(v){return Ext.util.Format.date(v,_13);};},stripTagsRE:/<\/?[^>]+>/gi,stripTags:function(v){return !v?v:String(v).replace(this.stripTagsRE,"");}};}();
+
+Ext.util.CSS=function(){var _1=null;var _2=document;var _3=/(-[a-z])/gi;var _4=function(m,a){return a.charAt(1).toUpperCase();};return {createStyleSheet:function(_7){var ss;if(Ext.isIE){ss=_2.createStyleSheet();ss.cssText=_7;}else{var _9=_2.getElementsByTagName("head")[0];var _a=_2.createElement("style");_a.setAttribute("type","text/css");try{_a.appendChild(_2.createTextNode(_7));}catch(e){_a.cssText=_7;}_9.appendChild(_a);ss=_a.styleSheet?_a.styleSheet:(_a.sheet||_2.styleSheets[_2.styleSheets.length-1]);}this.cacheStyleSheet(ss);return ss;},removeStyleSheet:function(id){var _c=_2.getElementById(id);if(_c){_c.parentNode.removeChild(_c);}},swapStyleSheet:function(id,_e){this.removeStyleSheet(id);var ss=_2.createElement("link");ss.setAttribute("rel","stylesheet");ss.setAttribute("type","text/css");ss.setAttribute("id",id);ss.setAttribute("href",_e);_2.getElementsByTagName("head")[0].appendChild(ss);},refreshCache:function(){return this.getRules(true);},cacheStyleSheet:function(ss){if(!_1){_1={};}try{var _11=ss.cssRules||ss.rules;for(var j=_11.length-1;j>=0;--j){_1[_11[j].selectorText]=_11[j];}}catch(e){}},getRules:function(_13){if(_1==null||_13){_1={};var ds=_2.styleSheets;for(var i=0,len=ds.length;i<len;i++){try{this.cacheStyleSheet(ds[i]);}catch(e){}}}return _1;},getRule:function(_17,_18){var rs=this.getRules(_18);if(!(_17 instanceof Array)){return rs[_17];}for(var i=0;i<_17.length;i++){if(rs[_17[i]]){return rs[_17[i]];}}return null;},updateRule:function(_1b,_1c,_1d){if(!(_1b instanceof Array)){var _1e=this.getRule(_1b);if(_1e){_1e.style[_1c.replace(_3,_4)]=_1d;return true;}}else{for(var i=0;i<_1b.length;i++){if(this.updateRule(_1b[i],_1c,_1d)){return true;}}}return false;}};}();
+
+Ext.util.ClickRepeater=function(el,_2){this.el=Ext.get(el);this.el.unselectable();Ext.apply(this,_2);this.events={"mousedown":true,"click":true,"mouseup":true};this.el.on("mousedown",this.handleMouseDown,this);if(this.preventDefault||this.stopDefault){this.el.on("click",function(e){if(this.preventDefault){e.preventDefault();}if(this.stopDefault){e.stopEvent();}},this);}if(this.handler){this.on("click",this.handler,this.scope||this);}Ext.util.ClickRepeater.superclass.constructor.call(this);};Ext.extend(Ext.util.ClickRepeater,Ext.util.Observable,{interval:20,delay:250,preventDefault:true,stopDefault:false,timer:0,docEl:Ext.get(document),handleMouseDown:function(){clearTimeout(this.timer);this.el.blur();if(this.pressClass){this.el.addClass(this.pressClass);}this.mousedownTime=new Date();this.docEl.on("mouseup",this.handleMouseUp,this);this.el.on("mouseout",this.handleMouseOut,this);this.fireEvent("mousedown",this);this.fireEvent("click",this);this.timer=this.click.defer(this.delay||this.interval,this);},click:function(){this.fireEvent("click",this);this.timer=this.click.defer(this.getInterval(),this);},getInterval:function(){if(!this.accelerate){return this.interval;}var _4=this.mousedownTime.getElapsed();if(_4<500){return 400;}else{if(_4<1700){return 320;}else{if(_4<2600){return 250;}else{if(_4<3500){return 180;}else{if(_4<4400){return 140;}else{if(_4<5300){return 80;}else{if(_4<6200){return 50;}else{return 10;}}}}}}}},handleMouseOut:function(){clearTimeout(this.timer);if(this.pressClass){this.el.removeClass(this.pressClass);}this.el.on("mouseover",this.handleMouseReturn,this);},handleMouseReturn:function(){this.el.un("mouseover",this.handleMouseReturn);if(this.pressClass){this.el.addClass(this.pressClass);}this.click();},handleMouseUp:function(){clearTimeout(this.timer);this.el.un("mouseover",this.handleMouseReturn);this.el.un("mouseout",this.handleMouseOut);this.docEl.un("mouseup",this.handleMouseUp);this.el.removeClass(this.pressClass);this.fireEvent("mouseup",this);}});
+
+Ext.KeyNav=function(el,_2){this.el=Ext.get(el);Ext.apply(this,_2);if(!this.disabled){this.disabled=true;this.enable();}};Ext.KeyNav.prototype={disabled:false,defaultEventAction:"stopEvent",prepareEvent:function(e){var k=e.getKey();var h=this.keyToHandler[k];if(Ext.isSafari&&h&&k>=37&&k<=40){e.stopEvent();}},relay:function(e){var k=e.getKey();var h=this.keyToHandler[k];if(h&&this[h]){if(this.doRelay(e,this[h],h)!==true){e[this.defaultEventAction]();}}},doRelay:function(e,h,_b){return h.call(this.scope||this,e);},enter:false,left:false,right:false,up:false,down:false,tab:false,esc:false,pageUp:false,pageDown:false,del:false,home:false,end:false,keyToHandler:{37:"left",39:"right",38:"up",40:"down",33:"pageUp",34:"pageDown",46:"del",36:"home",35:"end",13:"enter",27:"esc",9:"tab"},enable:function(){if(this.disabled){if(Ext.isIE){this.el.on("keydown",this.relay,this);}else{this.el.on("keydown",this.prepareEvent,this);this.el.on("keypress",this.relay,this);}this.disabled=false;}},disable:function(){if(!this.disabled){if(Ext.isIE){this.el.un("keydown",this.relay);}else{this.el.un("keydown",this.prepareEvent);this.el.un("keypress",this.relay);}this.disabled=true;}}};
+
+Ext.KeyMap=function(el,_2,_3){this.el=Ext.get(el);this.eventName=_3||"keydown";this.bindings=[];if(_2 instanceof Array){for(var i=0,_5=_2.length;i<_5;i++){this.addBinding(_2[i]);}}else{this.addBinding(_2);}this.keyDownDelegate=Ext.EventManager.wrap(this.handleKeyDown,this,true);this.enable();};Ext.KeyMap.prototype={stopEvent:false,addBinding:function(_6){var _7=_6.key,_8=_6.shift,_9=_6.ctrl,_a=_6.alt,fn=_6.fn,_c=_6.scope;if(typeof _7=="string"){var ks=[];var _e=_7.toUpperCase();for(var j=0,len=_e.length;j<len;j++){ks.push(_e.charCodeAt(j));}_7=ks;}var _11=_7 instanceof Array;var _12=function(e){if((!_8||e.shiftKey)&&(!_9||e.ctrlKey)&&(!_a||e.altKey)){var k=e.getKey();if(_11){for(var i=0,len=_7.length;i<len;i++){if(_7[i]==k){if(this.stopEvent){e.stopEvent();}fn.call(_c||window,k,e);return;}}}else{if(k==_7){if(this.stopEvent){e.stopEvent();}fn.call(_c||window,k,e);}}}};this.bindings.push(_12);},handleKeyDown:function(e){if(this.enabled){var b=this.bindings;for(var i=0,len=b.length;i<len;i++){b[i].call(this,e);}}},isEnabled:function(){return this.enabled;},enable:function(){if(!this.enabled){this.el.on(this.eventName,this.keyDownDelegate);this.enabled=true;}},disable:function(){if(this.enabled){this.el.removeListener(this.eventName,this.keyDownDelegate);this.enabled=false;}}};
+
+Ext.util.TextMetrics=function(){var _1;return {measure:function(el,_3,_4){if(!_1){_1=Ext.util.TextMetrics.Instance(el,_4);}_1.bind(el);_1.setFixedWidth(_4||"auto");return _1.getSize(_3);},createInstance:function(el,_6){return Ext.util.TextMetrics.Instance(el,_6);}};}();Ext.util.TextMetrics.Instance=function(_7,_8){var ml=new Ext.Element(document.createElement("div"));document.body.appendChild(ml.dom);ml.position("absolute");ml.setLeftTop(-1000,-1000);ml.hide();if(_8){mi.setWidth(_8);}var _a={getSize:function(_b){ml.update(_b);var s=ml.getSize();ml.update("");return s;},bind:function(el){ml.setStyle(Ext.fly(el).getStyles("font-size","font-style","font-weight","font-family","line-height"));},setFixedWidth:function(_e){ml.setWidth(_e);},getWidth:function(_f){ml.dom.style.width="auto";return this.getSize(_f).width;},getHeight:function(_10){return this.getSize(_10).height;}};_a.bind(_7);return _a;};Ext.Element.measureText=Ext.util.TextMetrics.measure;
+
+Ext.state.Provider=function(){Ext.state.Provider.superclass.constructor.call(this);this.events={"statechange":true};this.state={};Ext.state.Provider.superclass.constructor.call(this);};Ext.extend(Ext.state.Provider,Ext.util.Observable,{get:function(_1,_2){return typeof this.state[_1]=="undefined"?_2:this.state[_1];},clear:function(_3){delete this.state[_3];this.fireEvent("statechange",this,_3,null);},set:function(_4,_5){this.state[_4]=_5;this.fireEvent("statechange",this,_4,_5);},decodeValue:function(_6){var re=/^(a|n|d|b|s|o)\:(.*)$/;var _8=re.exec(unescape(_6));if(!_8||!_8[1]){return;}var _9=_8[1];var v=_8[2];switch(_9){case "n":return parseFloat(v);case "d":return new Date(Date.parse(v));case "b":return (v=="1");case "a":var _b=[];var _c=v.split("^");for(var i=0,_e=_c.length;i<_e;i++){_b.push(this.decodeValue(_c[i]));}return _b;case "o":var _b={};var _c=v.split("^");for(var i=0,_e=_c.length;i<_e;i++){var kv=_c[i].split("=");_b[kv[0]]=this.decodeValue(kv[1]);}return _b;default:return v;}},encodeValue:function(v){var enc;if(typeof v=="number"){enc="n:"+v;}else{if(typeof v=="boolean"){enc="b:"+(v?"1":"0");}else{if(v instanceof Date){enc="d:"+v.toGMTString();}else{if(v instanceof Array){var _12="";for(var i=0,len=v.length;i<len;i++){_12+=this.encodeValue(v[i]);if(i!=len-1){_12+="^";}}enc="a:"+_12;}else{if(typeof v=="object"){var _12="";for(var key in v){if(typeof v[key]!="function"){_12+=key+"="+this.encodeValue(v[key])+"^";}}enc="o:"+_12.substring(0,_12.length-1);}else{enc="s:"+v;}}}}}return escape(enc);}});Ext.state.Manager=function(){var _16=new Ext.state.Provider();return {setProvider:function(_17){_16=_17;},get:function(key,_19){return _16.get(key,_19);},set:function(key,_1b){_16.set(key,_1b);},clear:function(key){_16.clear(key);},getProvider:function(){return _16;}};}();Ext.state.CookieProvider=function(_1d){Ext.state.CookieProvider.superclass.constructor.call(this);this.path="/";this.expires=new Date(new Date().getTime()+(1000*60*60*24*7));this.domain=null;this.secure=false;Ext.apply(this,_1d);this.state=this.readCookies();};Ext.extend(Ext.state.CookieProvider,Ext.state.Provider,{set:function(_1e,_1f){if(typeof _1f=="undefined"||_1f===null){this.clear(_1e);return;}this.setCookie(_1e,_1f);Ext.state.CookieProvider.superclass.set.call(this,_1e,_1f);},clear:function(_20){this.clearCookie(_20);Ext.state.CookieProvider.superclass.clear.call(this,_20);},readCookies:function(){var _21={};var c=document.cookie+";";var re=/\s?(.*?)=(.*?);/g;var _24;while((_24=re.exec(c))!=null){var _25=_24[1];var _26=_24[2];if(_25&&_25.substring(0,3)=="ys-"){_21[_25.substr(3)]=this.decodeValue(_26);}}return _21;},setCookie:function(_27,_28){document.cookie="ys-"+_27+"="+this.encodeValue(_28)+((this.expires==null)?"":("; expires="+this.expires.toGMTString()))+((this.path==null)?"":("; path="+this.path))+((this.domain==null)?"":("; domain="+this.domain))+((this.secure==true)?"; secure":"");},clearCookie:function(_29){document.cookie="ys-"+_29+"=null; expires=Thu, 01-Jan-70 00:00:01 GMT"+((this.path==null)?"":("; path="+this.path))+((this.domain==null)?"":("; domain="+this.domain))+((this.secure==true)?"; secure":"");}});
+
+(function(){var _1=Ext.EventManager;var _2=Ext.lib.Dom;Ext.dd.DragDrop=function(id,_4,_5){if(id){this.init(id,_4,_5);}};Ext.dd.DragDrop.prototype={id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,b4StartDrag:function(x,y){},startDrag:function(x,y){},b4Drag:function(e){},onDrag:function(e){},onDragEnter:function(e,id){},b4DragOver:function(e){},onDragOver:function(e,id){},b4DragOut:function(e){},onDragOut:function(e,id){},b4DragDrop:function(e){},onDragDrop:function(e,id){},onInvalidDrop:function(e){},b4EndDrag:function(e){},endDrag:function(e){},b4MouseDown:function(e){},onMouseDown:function(e){},onMouseUp:function(e){},onAvailable:function(){},defaultPadding:{left:0,right:0,top:0,bottom:0},constrainTo:function(_1d,pad,_1f){if(typeof pad=="number"){pad={left:pad,right:pad,top:pad,bottom:pad};}pad=pad||this.defaultPadding;var b=Ext.get(this.getEl()).getBox();var ce=Ext.get(_1d);var c=ce.dom==document.body?{x:0,y:0,width:Ext.lib.Dom.getViewWidth(),height:Ext.lib.Dom.getViewHeight()}:ce.getBox(_1f||false);var _23=b.y-c.y;var _24=b.x-c.x;this.resetConstraints();this.setXConstraint(_24-(pad.left||0),c.width-_24-b.width-(pad.right||0));this.setYConstraint(_23-(pad.top||0),c.height-_23-b.height-(pad.bottom||0));},getEl:function(){if(!this._domRef){this._domRef=Ext.getDom(this.id);}return this._domRef;},getDragEl:function(){return Ext.getDom(this.dragElId);},init:function(id,_26,_27){this.initTarget(id,_26,_27);_1.on(this.id,"mousedown",this.handleMouseDown,this);},initTarget:function(id,_29,_2a){this.config=_2a||{};this.DDM=Ext.dd.DDM;this.groups={};if(typeof id!=="string"){id=Ext.id(id);}this.id=id;this.addToGroup((_29)?_29:"default");this.handleElId=id;this.setDragElId(id);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();this.handleOnAvailable();},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable();},setPadding:function(_2b,_2c,_2d,_2e){if(!_2c&&0!==_2c){this.padding=[_2b,_2b,_2b,_2b];}else{if(!_2d&&0!==_2d){this.padding=[_2b,_2c,_2b,_2c];}else{this.padding=[_2b,_2c,_2d,_2e];}}},setInitPosition:function(_2f,_30){var el=this.getEl();if(!this.DDM.verifyEl(el)){return;}var dx=_2f||0;var dy=_30||0;var p=_2.getXY(el);this.initPageX=p[0]-dx;this.initPageY=p[1]-dy;this.lastPageX=p[0];this.lastPageY=p[1];this.setStartPosition(p);},setStartPosition:function(pos){var p=pos||_2.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=p[0];this.startPageY=p[1];},addToGroup:function(_37){this.groups[_37]=true;this.DDM.regDragDrop(this,_37);},removeFromGroup:function(_38){if(this.groups[_38]){delete this.groups[_38];}this.DDM.removeDDFromGroup(this,_38);},setDragElId:function(id){this.dragElId=id;},setHandleElId:function(id){if(typeof id!=="string"){id=Ext.id(id);}this.handleElId=id;this.DDM.regHandle(this.id,id);},setOuterHandleElId:function(id){if(typeof id!=="string"){id=Ext.id(id);}_1.on(id,"mousedown",this.handleMouseDown,this);this.setHandleElId(id);this.hasOuterHandles=true;},unreg:function(){_1.un(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return (this.DDM.isLocked()||this.locked);},handleMouseDown:function(e,oDD){if(this.primaryButtonOnly&&e.button!=0){return;}if(this.isLocked()){return;}this.DDM.refreshCache(this.groups);var pt=new Ext.lib.Point(Ext.lib.Event.getPageX(e),Ext.lib.Event.getPageY(e));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(pt,this)){}else{if(this.clickValidator(e)){this.setStartPosition();this.b4MouseDown(e);this.onMouseDown(e);this.DDM.handleMouseDown(e,this);this.DDM.stopEvent(e);}else{}}},clickValidator:function(e){var _40=Ext.lib.Event.getTarget(e);return (this.isValidHandleChild(_40)&&(this.id==this.handleElId||this.DDM.handleWasClicked(_40,this.id)));},addInvalidHandleType:function(_41){var _42=_41.toUpperCase();this.invalidHandleTypes[_42]=_42;},addInvalidHandleId:function(id){if(typeof id!=="string"){id=Ext.id(id);}this.invalidHandleIds[id]=id;},addInvalidHandleClass:function(_44){this.invalidHandleClasses.push(_44);},removeInvalidHandleType:function(_45){var _46=_45.toUpperCase();delete this.invalidHandleTypes[_46];},removeInvalidHandleId:function(id){if(typeof id!=="string"){id=Ext.id(id);}delete this.invalidHandleIds[id];},removeInvalidHandleClass:function(_48){for(var i=0,len=this.invalidHandleClasses.length;i<len;++i){if(this.invalidHandleClasses[i]==_48){delete this.invalidHandleClasses[i];}}},isValidHandleChild:function(_4b){var _4c=true;var _4d;try{_4d=_4b.nodeName.toUpperCase();}catch(e){_4d=_4b.nodeName;}_4c=_4c&&!this.invalidHandleTypes[_4d];_4c=_4c&&!this.invalidHandleIds[_4b.id];for(var i=0,len=this.invalidHandleClasses.length;_4c&&i<len;++i){_4c=!_2.hasClass(_4b,this.invalidHandleClasses[i]);}return _4c;},setXTicks:function(_50,_51){this.xTicks=[];this.xTickSize=_51;var _52={};for(var i=this.initPageX;i>=this.minX;i=i-_51){if(!_52[i]){this.xTicks[this.xTicks.length]=i;_52[i]=true;}}for(i=this.initPageX;i<=this.maxX;i=i+_51){if(!_52[i]){this.xTicks[this.xTicks.length]=i;_52[i]=true;}}this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(_54,_55){this.yTicks=[];this.yTickSize=_55;var _56={};for(var i=this.initPageY;i>=this.minY;i=i-_55){if(!_56[i]){this.yTicks[this.yTicks.length]=i;_56[i]=true;}}for(i=this.initPageY;i<=this.maxY;i=i+_55){if(!_56[i]){this.yTicks[this.yTicks.length]=i;_56[i]=true;}}this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(_58,_59,_5a){this.leftConstraint=_58;this.rightConstraint=_59;this.minX=this.initPageX-_58;this.maxX=this.initPageX+_59;if(_5a){this.setXTicks(this.initPageX,_5a);}this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(iUp,_5c,_5d){this.topConstraint=iUp;this.bottomConstraint=_5c;this.minY=this.initPageY-iUp;this.maxY=this.initPageY+_5c;if(_5d){this.setYTicks(this.initPageY,_5d);}this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var dx=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var dy=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(dx,dy);}else{this.setInitPosition();}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(val,_61){if(!_61){return val;}else{if(_61[0]>=val){return _61[0];}else{for(var i=0,len=_61.length;i<len;++i){var _64=i+1;if(_61[_64]&&_61[_64]>=val){var _65=val-_61[i];var _66=_61[_64]-val;return (_66>_65)?_61[i]:_61[_64];}}return _61[_61.length-1];}}},toString:function(){return ("DragDrop "+this.id);}};})();if(!Ext.dd.DragDropMgr){Ext.dd.DragDropMgr=function(){var _67=Ext.EventManager;return {ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initalized:false,locked:false,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,mode:0,_execOnAll:function(_68,_69){for(var i in this.ids){for(var j in this.ids[i]){var oDD=this.ids[i][j];if(!this.isTypeOfDD(oDD)){continue;}oDD[_68].apply(oDD,_69);}}},_onLoad:function(){this.init();_67.on(document,"mouseup",this.handleMouseUp,this,true);_67.on(document,"mousemove",this.handleMouseMove,this,true);_67.on(window,"unload",this._onUnload,this,true);_67.on(window,"resize",this._onResize,this,true);},_onResize:function(e){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:350,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,regDragDrop:function(oDD,_6f){if(!this.initialized){this.init();}if(!this.ids[_6f]){this.ids[_6f]={};}this.ids[_6f][oDD.id]=oDD;},removeDDFromGroup:function(oDD,_71){if(!this.ids[_71]){this.ids[_71]={};}var obj=this.ids[_71];if(obj&&obj[oDD.id]){delete obj[oDD.id];}},_remove:function(oDD){for(var g in oDD.groups){if(g&&this.ids[g][oDD.id]){delete this.ids[g][oDD.id];}}delete this.handleIds[oDD.id];},regHandle:function(_75,_76){if(!this.handleIds[_75]){this.handleIds[_75]={};}this.handleIds[_75][_76]=_76;},isDragDrop:function(id){return (this.getDDById(id))?true:false;},getRelated:function(_78,_79){var _7a=[];for(var i in _78.groups){for(j in this.ids[i]){var dd=this.ids[i][j];if(!this.isTypeOfDD(dd)){continue;}if(!_79||dd.isTarget){_7a[_7a.length]=dd;}}}return _7a;},isLegalTarget:function(oDD,_7e){var _7f=this.getRelated(oDD,true);for(var i=0,len=_7f.length;i<len;++i){if(_7f[i].id==_7e.id){return true;}}return false;},isTypeOfDD:function(oDD){return (oDD&&oDD.__ygDragDrop);},isHandle:function(_83,_84){return (this.handleIds[_83]&&this.handleIds[_83][_84]);},getDDById:function(id){for(var i in this.ids){if(this.ids[i][id]){return this.ids[i][id];}}return null;},handleMouseDown:function(e,oDD){this.currentTarget=Ext.lib.Event.getTarget(e);this.dragCurrent=oDD;var el=oDD.getEl();this.startX=Ext.lib.Event.getPageX(e);this.startY=Ext.lib.Event.getPageY(e);this.deltaX=this.startX-el.offsetLeft;this.deltaY=this.startY-el.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var DDM=Ext.dd.DDM;DDM.startDrag(DDM.startX,DDM.startY);},this.clickTimeThresh);},startDrag:function(x,y){clearTimeout(this.clickTimeout);if(this.dragCurrent){this.dragCurrent.b4StartDrag(x,y);this.dragCurrent.startDrag(x,y);}this.dragThreshMet=true;},handleMouseUp:function(e){if(!this.dragCurrent){return;}clearTimeout(this.clickTimeout);if(this.dragThreshMet){this.fireEvents(e,true);}else{}this.stopDrag(e);this.stopEvent(e);},stopEvent:function(e){if(this.stopPropagation){e.stopPropagation();}if(this.preventDefault){e.preventDefault();}},stopDrag:function(e){if(this.dragCurrent){if(this.dragThreshMet){this.dragCurrent.b4EndDrag(e);this.dragCurrent.endDrag(e);}this.dragCurrent.onMouseUp(e);}this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(e){if(!this.dragCurrent){return true;}if(Ext.isIE&&(e.button!==0&&e.button!==1&&e.button!==2)){this.stopEvent(e);return this.handleMouseUp(e);}if(!this.dragThreshMet){var _91=Math.abs(this.startX-Ext.lib.Event.getPageX(e));var _92=Math.abs(this.startY-Ext.lib.Event.getPageY(e));if(_91>this.clickPixelThresh||_92>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}}if(this.dragThreshMet){this.dragCurrent.b4Drag(e);this.dragCurrent.onDrag(e);this.fireEvents(e,false);}this.stopEvent(e);return true;},fireEvents:function(e,_94){var dc=this.dragCurrent;if(!dc||dc.isLocked()){return;}var x=Ext.lib.Event.getPageX(e);var y=Ext.lib.Event.getPageY(e);var pt=new Ext.lib.Point(x,y);var _99=[];var _9a=[];var _9b=[];var _9c=[];var _9d=[];for(var i in this.dragOvers){var ddo=this.dragOvers[i];if(!this.isTypeOfDD(ddo)){continue;}if(!this.isOverTarget(pt,ddo,this.mode)){_9a.push(ddo);}_99[i]=true;delete this.dragOvers[i];}for(var _a0 in dc.groups){if("string"!=typeof _a0){continue;}for(i in this.ids[_a0]){var oDD=this.ids[_a0][i];if(!this.isTypeOfDD(oDD)){continue;}if(oDD.isTarget&&!oDD.isLocked()&&oDD!=dc){if(this.isOverTarget(pt,oDD,this.mode)){if(_94){_9c.push(oDD);}else{if(!_99[oDD.id]){_9d.push(oDD);}else{_9b.push(oDD);}this.dragOvers[oDD.id]=oDD;}}}}}if(this.mode){if(_9a.length){dc.b4DragOut(e,_9a);dc.onDragOut(e,_9a);}if(_9d.length){dc.onDragEnter(e,_9d);}if(_9b.length){dc.b4DragOver(e,_9b);dc.onDragOver(e,_9b);}if(_9c.length){dc.b4DragDrop(e,_9c);dc.onDragDrop(e,_9c);}}else{var len=0;for(i=0,len=_9a.length;i<len;++i){dc.b4DragOut(e,_9a[i].id);dc.onDragOut(e,_9a[i].id);}for(i=0,len=_9d.length;i<len;++i){dc.onDragEnter(e,_9d[i].id);}for(i=0,len=_9b.length;i<len;++i){dc.b4DragOver(e,_9b[i].id);dc.onDragOver(e,_9b[i].id);}for(i=0,len=_9c.length;i<len;++i){dc.b4DragDrop(e,_9c[i].id);dc.onDragDrop(e,_9c[i].id);}}if(_94&&!_9c.length){dc.onInvalidDrop(e);}},getBestMatch:function(dds){var _a4=null;var len=dds.length;if(len==1){_a4=dds[0];}else{for(var i=0;i<len;++i){var dd=dds[i];if(dd.cursorIsOver){_a4=dd;break;}else{if(!_a4||_a4.overlap.getArea()<dd.overlap.getArea()){_a4=dd;}}}}return _a4;},refreshCache:function(_a8){for(var _a9 in _a8){if("string"!=typeof _a9){continue;}for(var i in this.ids[_a9]){var oDD=this.ids[_a9][i];if(this.isTypeOfDD(oDD)){var loc=this.getLocation(oDD);if(loc){this.locationCache[oDD.id]=loc;}else{delete this.locationCache[oDD.id];}}}}},verifyEl:function(el){try{if(el){var _ae=el.offsetParent;if(_ae){return true;}}}catch(e){}return false;},getLocation:function(oDD){if(!this.isTypeOfDD(oDD)){return null;}var el=oDD.getEl(),pos,x1,x2,y1,y2,t,r,b,l;try{pos=Ext.lib.Dom.getXY(el);}catch(e){}if(!pos){return null;}x1=pos[0];x2=x1+el.offsetWidth;y1=pos[1];y2=y1+el.offsetHeight;t=y1-oDD.padding[0];r=x2+oDD.padding[1];b=y2+oDD.padding[2];l=x1-oDD.padding[3];return new Ext.lib.Region(t,r,b,l);},isOverTarget:function(pt,_bb,_bc){var loc=this.locationCache[_bb.id];if(!loc||!this.useCache){loc=this.getLocation(_bb);this.locationCache[_bb.id]=loc;}if(!loc){return false;}_bb.cursorIsOver=loc.contains(pt);var dc=this.dragCurrent;if(!dc||!dc.getTargetCoord||(!_bc&&!dc.constrainX&&!dc.constrainY)){return _bb.cursorIsOver;}_bb.overlap=null;var pos=dc.getTargetCoord(pt.x,pt.y);var el=dc.getDragEl();var _c1=new Ext.lib.Region(pos.y,pos.x+el.offsetWidth,pos.y+el.offsetHeight,pos.x);var _c2=_c1.intersect(loc);if(_c2){_bb.overlap=_c2;return (_bc)?true:_bb.cursorIsOver;}else{return false;}},_onUnload:function(e,me){Ext.dd.DragDropMgr.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=null;}this._execOnAll("unreg",[]);for(i in this.elementCache){delete this.elementCache[i];}this.elementCache={};this.ids={};},elementCache:{},getElWrapper:function(id){var _c6=this.elementCache[id];if(!_c6||!_c6.el){_c6=this.elementCache[id]=new this.ElementWrapper(Ext.getDom(id));}return _c6;},getElement:function(id){return Ext.getDom(id);},getCss:function(id){var el=Ext.getDom(id);return (el)?el.style:null;},ElementWrapper:function(el){this.el=el||null;this.id=this.el&&el.id;this.css=this.el&&el.style;},getPosX:function(el){return Ext.lib.Dom.getX(el);},getPosY:function(el){return Ext.lib.Dom.getY(el);},swapNode:function(n1,n2){if(n1.swapNode){n1.swapNode(n2);}else{var p=n2.parentNode;var s=n2.nextSibling;if(s==n1){p.insertBefore(n1,n2);}else{if(n2==n1.nextSibling){p.insertBefore(n2,n1);}else{n1.parentNode.replaceChild(n2,n1);p.insertBefore(n1,s);}}}},getScroll:function(){var t,l,dde=document.documentElement,db=document.body;if(dde&&(dde.scrollTop||dde.scrollLeft)){t=dde.scrollTop;l=dde.scrollLeft;}else{if(db){t=db.scrollTop;l=db.scrollLeft;}else{}}return {top:t,left:l};},getStyle:function(el,_d6){return Ext.fly(el).getStyle(_d6);},getScrollTop:function(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(_d7,_d8){var _d9=Ext.lib.Dom.getXY(_d8);Ext.lib.Dom.setXY(_d7,_d9);},numericSort:function(a,b){return (a-b);},_timeoutCount:0,_addListeners:function(){var DDM=Ext.dd.DDM;if(Ext.lib.Event&&document){DDM._onLoad();}else{if(DDM._timeoutCount>2000){}else{setTimeout(DDM._addListeners,10);if(document&&document.body){DDM._timeoutCount+=1;}}}},handleWasClicked:function(_dd,id){if(this.isHandle(id,_dd.id)){return true;}else{var p=_dd.parentNode;while(p){if(this.isHandle(id,p.id)){return true;}else{p=p.parentNode;}}}return false;}};}();Ext.dd.DDM=Ext.dd.DragDropMgr;Ext.dd.DDM._addListeners();}Ext.dd.DD=function(id,_e1,_e2){if(id){this.init(id,_e1,_e2);}};Ext.extend(Ext.dd.DD,Ext.dd.DragDrop,{scroll:true,autoOffset:function(_e3,_e4){var x=_e3-this.startPageX;var y=_e4-this.startPageY;this.setDelta(x,y);},setDelta:function(_e7,_e8){this.deltaX=_e7;this.deltaY=_e8;},setDragElPos:function(_e9,_ea){var el=this.getDragEl();this.alignElWithMouse(el,_e9,_ea);},alignElWithMouse:function(el,_ed,_ee){var _ef=this.getTargetCoord(_ed,_ee);var fly=Ext.fly(el);if(!this.deltaSetXY){var _f1=[_ef.x,_ef.y];fly.setXY(_f1);var _f2=fly.getLeft(true);var _f3=fly.getTop(true);this.deltaSetXY=[_f2-_ef.x,_f3-_ef.y];}else{fly.setLeftTop(_ef.x+this.deltaSetXY[0],_ef.y+this.deltaSetXY[1]);}this.cachePosition(_ef.x,_ef.y);this.autoScroll(_ef.x,_ef.y,el.offsetHeight,el.offsetWidth);},cachePosition:function(_f4,_f5){if(_f4){this.lastPageX=_f4;this.lastPageY=_f5;}else{var _f6=Ext.lib.Dom.getXY(this.getEl());this.lastPageX=_f6[0];this.lastPageY=_f6[1];}},autoScroll:function(x,y,h,w){if(this.scroll){var _fb=Ext.lib.Dom.getViewWidth();var _fc=Ext.lib.Dom.getViewHeight();var st=this.DDM.getScrollTop();var sl=this.DDM.getScrollLeft();var bot=h+y;var _100=w+x;var _101=(_fb+st-y-this.deltaY);var _102=(_fc+sl-x-this.deltaX);var _103=40;var _104=(document.all)?80:30;if(bot>_fb&&_101<_103){window.scrollTo(sl,st+_104);}if(y<st&&st>0&&y-st<_103){window.scrollTo(sl,st-_104);}if(_100>_fc&&_102<_103){window.scrollTo(sl+_104,st);}if(x<sl&&sl>0&&x-sl<_103){window.scrollTo(sl-_104,st);}}},getTargetCoord:function(_105,_106){var x=_105-this.deltaX;var y=_106-this.deltaY;if(this.constrainX){if(x<this.minX){x=this.minX;}if(x>this.maxX){x=this.maxX;}}if(this.constrainY){if(y<this.minY){y=this.minY;}if(y>this.maxY){y=this.maxY;}}x=this.getTick(x,this.xTicks);y=this.getTick(y,this.yTicks);return {x:x,y:y};},applyConfig:function(){Ext.dd.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(e){this.autoOffset(Ext.lib.Event.getPageX(e),Ext.lib.Event.getPageY(e));},b4Drag:function(e){this.setDragElPos(Ext.lib.Event.getPageX(e),Ext.lib.Event.getPageY(e));},toString:function(){return ("DD "+this.id);}});Ext.dd.DDProxy=function(id,_10c,_10d){if(id){this.init(id,_10c,_10d);this.initFrame();}};Ext.dd.DDProxy.dragElId="ygddfdiv";Ext.extend(Ext.dd.DDProxy,Ext.dd.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var self=this;var body=document.body;if(!body||!body.firstChild){setTimeout(function(){self.createFrame();},50);return;}var div=this.getDragEl();if(!div){div=document.createElement("div");div.id=this.dragElId;var s=div.style;s.position="absolute";s.visibility="hidden";s.cursor="move";s.border="2px solid #aaa";s.zIndex=999;body.insertBefore(div,body.firstChild);}},initFrame:function(){this.createFrame();},applyConfig:function(){Ext.dd.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||Ext.dd.DDProxy.dragElId);},showFrame:function(_112,_113){var el=this.getEl();var _115=this.getDragEl();var s=_115.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(s.width,10)/2),Math.round(parseInt(s.height,10)/2));}this.setDragElPos(_112,_113);Ext.fly(_115).show();},_resizeProxy:function(){if(this.resizeFrame){var el=this.getEl();Ext.fly(this.getDragEl()).setSize(el.offsetWidth,el.offsetHeight);}},b4MouseDown:function(e){var x=Ext.lib.Event.getPageX(e);var y=Ext.lib.Event.getPageY(e);this.autoOffset(x,y);this.setDragElPos(x,y);},b4StartDrag:function(x,y){this.showFrame(x,y);},b4EndDrag:function(e){Ext.fly(this.getDragEl()).hide();},endDrag:function(e){var lel=this.getEl();var del=this.getDragEl();del.style.visibility="";lel.style.visibility="hidden";Ext.dd.DDM.moveToEl(lel,del);del.style.visibility="hidden";lel.style.visibility="";},toString:function(){return ("DDProxy "+this.id);}});Ext.dd.DDTarget=function(id,_122,_123){if(id){this.initTarget(id,_122,_123);}};Ext.extend(Ext.dd.DDTarget,Ext.dd.DragDrop,{toString:function(){return ("DDTarget "+this.id);}});
+
+Ext.dd.ScrollManager=function(){var _1=Ext.dd.DragDropMgr;var _2={};var _3=null;var _4={};var _5=function(e){_3=null;_7();};var _8=function(){if(_1.dragCurrent){_1.refreshCache(_1.dragCurrent.groups);}};var _9=function(){if(_1.dragCurrent){var _a=Ext.dd.ScrollManager;if(!_a.animate){if(_4.el.scroll(_4.dir,_a.increment)){_8();}}else{_4.el.scroll(_4.dir,_a.increment,true,_a.animDuration,_8);}}};var _7=function(){if(_4.id){clearInterval(_4.id);}_4.id=0;_4.el=null;_4.dir="";};var _b=function(el,_d){_7();_4.el=el;_4.dir=_d;_4.id=setInterval(_9,Ext.dd.ScrollManager.frequency);};var _e=function(e,_10){if(_10||!_1.dragCurrent){return;}var dds=Ext.dd.ScrollManager;if(!_3||_3!=_1.dragCurrent){_3=_1.dragCurrent;dds.refreshCache();}var xy=Ext.lib.Event.getXY(e);var pt=new Ext.lib.Point(xy[0],xy[1]);for(var id in _2){var el=_2[id],r=el._region;if(r.contains(pt)&&el.isScrollable()){if(r.bottom-pt.y<=dds.thresh){if(_4.el!=el){_b(el,"down");}return;}else{if(r.right-pt.x<=dds.thresh){if(_4.el!=el){_b(el,"left");}return;}else{if(pt.y-r.top<=dds.thresh){if(_4.el!=el){_b(el,"up");}return;}else{if(pt.x-r.left<=dds.thresh){if(_4.el!=el){_b(el,"right");}return;}}}}}}_7();};_1.fireEvents=_1.fireEvents.createSequence(_e,_1);_1.stopDrag=_1.stopDrag.createSequence(_5,_1);return {register:function(el){if(el instanceof Array){for(var i=0,len=el.length;i<len;i++){this.register(el[i]);}}else{el=Ext.get(el);_2[el.id]=el;}},unregister:function(el){if(el instanceof Array){for(var i=0,len=el.length;i<len;i++){this.unregister(el[i]);}}else{el=Ext.get(el);delete _2[el.id];}},thresh:25,increment:100,frequency:500,animate:true,animDuration:0.4,refreshCache:function(){for(var id in _2){if(typeof _2[id]=="object"){_2[id]._region=_2[id].getRegion();}}}};}();
+
+Ext.dd.Registry=function(){var _1={};var _2={};var _3=0;var _4=function(el,_6){if(typeof el=="string"){return el;}var id=el.id;if(!id&&_6!==false){id="yddgen-"+(++_3);el.id=id;}return id;};return {register:function(el,_9){_9=_9||{};if(typeof el=="string"){el=document.getElementById(el);}_9.ddel=el;_1[_4(el)]=_9;if(_9.isHandle!==false){_2[_9.ddel.id]=_9;}if(_9.handles){var hs=_9.handles;for(var i=0,_c=hs.length;i<_c;i++){_2[_4(hs[i])]=_9;}}},unregister:function(el){var id=_4(el,false);var _f=_1[id];if(_f){delete _1[id];if(_f.handles){var hs=_f.handles;for(var i=0,len=hs.length;i<len;i++){delete _2[_4(hs[i],false)];}}}},getHandle:function(id){if(typeof id!="string"){id=id.id;}return _2[id];},getHandleFromEvent:function(e){var t=Ext.lib.Event.getTarget(e);return t?_2[t.id]:null;},getTarget:function(id){if(typeof id!="string"){id=id.id;}return _1[id];},getTargetFromEvent:function(e){var t=Ext.lib.Event.getTarget(e);return t?_1[t.id]||_2[t.id]:null;}};}();
+
+Ext.dd.StatusProxy=function(_1){Ext.apply(this,_1);this.id=this.id||Ext.id();this.el=new Ext.Layer({dh:{id:this.id,tag:"div",cls:"x-dd-drag-proxy "+this.dropNotAllowed,children:[{tag:"div",cls:"x-dd-drop-icon"},{tag:"div",cls:"x-dd-drag-ghost"}]},shadow:!_1||_1.shadow!==false});this.ghost=Ext.get(this.el.dom.childNodes[1]);this.dropStatus=this.dropNotAllowed;};Ext.dd.StatusProxy.prototype={dropAllowed:"x-dd-drop-ok",dropNotAllowed:"x-dd-drop-nodrop",setStatus:function(_2){_2=_2||this.dropNotAllowed;if(this.dropStatus!=_2){this.el.replaceClass(this.dropStatus,_2);this.dropStatus=_2;}},reset:function(_3){this.el.dom.className="x-dd-drag-proxy "+this.dropNotAllowed;this.dropStatus=this.dropNotAllowed;if(_3){this.ghost.update("");}},update:function(_4){if(typeof _4=="string"){this.ghost.update(_4);}else{this.ghost.update("");_4.style.margin="0";this.ghost.dom.appendChild(_4);}},getEl:function(){return this.el;},getGhost:function(){return this.ghost;},hide:function(_5){this.el.hide();if(_5){this.reset(true);}},stop:function(){if(this.anim&&this.anim.isAnimated&&this.anim.isAnimated()){this.anim.stop();}},show:function(){this.el.show();},sync:function(){this.el.sync();},repair:function(xy,_7,_8){this.callback=_7;this.scope=_8;if(xy&&this.animRepair!==false){this.el.addClass("x-dd-drag-repair");this.el.hideUnders(true);this.anim=this.el.shift({duration:this.repairDuration||0.5,easing:"easeOut",xy:xy,stopFx:true,callback:this.afterRepair,scope:this});}else{this.afterRepair();}},afterRepair:function(){this.hide(true);if(typeof this.callback=="function"){this.callback.call(this.scope||this);}this.callback==null;this.scope==null;}};
+
+Ext.dd.DragSource=function(el,_2){this.el=Ext.get(el);this.dragData={};Ext.apply(this,_2);if(!this.proxy){this.proxy=new Ext.dd.StatusProxy();}this.el.on("mouseup",this.handleMouseUp);Ext.dd.DragSource.superclass.constructor.call(this,this.el.dom,this.ddGroup||this.group,{dragElId:this.proxy.id,resizeFrame:false,isTarget:false,scroll:this.scroll===true});this.dragging=false;};Ext.extend(Ext.dd.DragSource,Ext.dd.DDProxy,{dropAllowed:"x-dd-drop-ok",dropNotAllowed:"x-dd-drop-nodrop",getDragData:function(e){return this.dragData;},onDragEnter:function(e,id){var _6=Ext.dd.DragDropMgr.getDDById(id);this.cachedTarget=_6;if(this.beforeDragEnter(_6,e,id)!==false){if(_6.isNotifyTarget){var _7=_6.notifyEnter(this,e,this.dragData);this.proxy.setStatus(_7);}else{this.proxy.setStatus(this.dropAllowed);}if(this.afterDragEnter){this.afterDragEnter(_6,e,id);}}},beforeDragEnter:function(_8,e,id){return true;},alignElWithMouse:function(){Ext.dd.DragSource.superclass.alignElWithMouse.apply(this,arguments);this.proxy.sync();},onDragOver:function(e,id){var _d=this.cachedTarget||Ext.dd.DragDropMgr.getDDById(id);if(this.beforeDragOver(_d,e,id)!==false){if(_d.isNotifyTarget){var _e=_d.notifyOver(this,e,this.dragData);this.proxy.setStatus(_e);}if(this.afterDragOver){this.afterDragOver(_d,e,id);}}},beforeDragOver:function(_f,e,id){return true;},onDragOut:function(e,id){var _14=this.cachedTarget||Ext.dd.DragDropMgr.getDDById(id);if(this.beforeDragOut(_14,e,id)!==false){if(_14.isNotifyTarget){_14.notifyOut(this,e,this.dragData);}this.proxy.reset();if(this.afterDragOut){this.afterDragOut(_14,e,id);}}this.cachedTarget=null;},beforeDragOut:function(_15,e,id){return true;},onDragDrop:function(e,id){var _1a=this.cachedTarget||Ext.dd.DragDropMgr.getDDById(id);if(this.beforeDragDrop(_1a,e,id)!==false){if(_1a.isNotifyTarget){if(_1a.notifyDrop(this,e,this.dragData)){this.onValidDrop(_1a,e,id);}else{this.onInvalidDrop(_1a,e,id);}}else{this.onValidDrop(_1a,e,id);}if(this.afterDragDrop){this.afterDragDrop(_1a,e,id);}}},beforeDragDrop:function(_1b,e,id){return true;},onValidDrop:function(_1e,e,id){this.hideProxy();},getRepairXY:function(e,_22){return this.el.getXY();},onInvalidDrop:function(_23,e,id){this.beforeInvalidDrop(_23,e,id);if(this.cachedTarget){if(this.cachedTarget.isNotifyTarget){this.cachedTarget.notifyOut(this,e,this.dragData);}this.cacheTarget=null;}this.proxy.repair(this.getRepairXY(e,this.dragData),this.afterRepair,this);if(this.afterInvalidDrop){this.afterInvalidDrop(e,id);}},afterRepair:function(){if(Ext.enableFx){this.el.highlight(this.hlColor||"c3daf9");}this.dragging=false;},beforeInvalidDrop:function(_26,e,id){return true;},handleMouseDown:function(e){if(this.dragging){return;}if(Ext.QuickTips){Ext.QuickTips.disable();}var _2a=this.getDragData(e);if(_2a&&this.onBeforeDrag(_2a,e)!==false){this.dragData=_2a;this.proxy.stop();Ext.dd.DragSource.superclass.handleMouseDown.apply(this,arguments);}},handleMouseUp:function(e){if(Ext.QuickTips){Ext.QuickTips.enable();}},onBeforeDrag:function(_2c,e){return true;},onStartDrag:Ext.emptyFn,startDrag:function(e){this.proxy.reset();this.dragging=true;this.proxy.update("");this.onInitDrag(e);this.proxy.show();},onInitDrag:function(e){var _30=this.el.dom.cloneNode(true);_30.id=Ext.id();this.proxy.update(_30);this.onStartDrag(e);return true;},getProxy:function(){return this.proxy;},hideProxy:function(){this.proxy.hide();this.proxy.reset(true);this.dragging=false;},triggerCacheRefresh:function(){Ext.dd.DDM.refreshCache(this.groups);},b4EndDrag:function(e){},endDrag:function(e){this.onEndDrag(this.dragData,e);},onEndDrag:function(_33,e){},autoOffset:function(x,y){this.setDelta(-12,-20);}});
+
+Ext.dd.DropTarget=function(el,_2){this.el=Ext.get(el);Ext.apply(this,_2);if(this.containerScroll){Ext.dd.ScrollManager.register(this.el);}Ext.dd.DropTarget.superclass.constructor.call(this,this.el.dom,this.ddGroup||this.group,{isTarget:true});};Ext.extend(Ext.dd.DropTarget,Ext.dd.DDTarget,{dropAllowed:"x-dd-drop-ok",dropNotAllowed:"x-dd-drop-nodrop",isTarget:true,isNotifyTarget:true,notifyEnter:function(dd,e,_5){if(this.overClass){this.el.addClass(this.overClass);}return this.dropAllowed;},notifyOver:function(dd,e,_8){return this.dropAllowed;},notifyOut:function(dd,e,_b){if(this.overClass){this.el.removeClass(this.overClass);}},notifyDrop:function(dd,e,_e){return false;}});
+
+Ext.dd.DragZone=function(el,_2){Ext.dd.DragZone.superclass.constructor.call(this,el,_2);if(this.containerScroll){Ext.dd.ScrollManager.register(this.el);}};Ext.extend(Ext.dd.DragZone,Ext.dd.DragSource,{getDragData:function(e){return Ext.dd.Registry.getHandleFromEvent(e);},onInitDrag:function(e){this.proxy.update(this.dragData.ddel.cloneNode(true));this.onStartDrag(e);return true;},afterRepair:function(){if(Ext.enableFx){Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor||"c3daf9");}this.dragging=false;},getRepairXY:function(e){return Ext.Element.fly(this.dragData.ddel).getXY();}});
+
+Ext.dd.DropZone=function(el,_2){Ext.dd.DropZone.superclass.constructor.call(this,el,_2);};Ext.extend(Ext.dd.DropZone,Ext.dd.DropTarget,{getTargetFromEvent:function(e){return Ext.dd.Registry.getTargetFromEvent(e);},onNodeEnter:function(n,dd,e,_7){},onNodeOver:function(n,dd,e,_b){return this.dropAllowed;},onNodeOut:function(n,dd,e,_f){},onNodeDrop:function(n,dd,e,_13){return false;},onContainerOver:function(dd,e,_16){return this.dropNotAllowed;},onContainerDrop:function(dd,e,_19){return false;},notifyEnter:function(dd,e,_1c){return this.dropNotAllowed;},notifyOver:function(dd,e,_1f){var n=this.getTargetFromEvent(e);if(!n){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,dd,e,_1f);this.lastOverNode=null;}return this.onContainerOver(dd,e,_1f);}if(this.lastOverNode!=n){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,dd,e,_1f);}this.onNodeEnter(n,dd,e,_1f);this.lastOverNode=n;}return this.onNodeOver(n,dd,e,_1f);},notifyOut:function(dd,e,_23){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,dd,e,_23);this.lastOverNode=null;}},notifyDrop:function(dd,e,_26){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,dd,e,_26);this.lastOverNode=null;}var n=this.getTargetFromEvent(e);return n?this.onNodeDrop(n,dd,e,_26):this.onContainerDrop(dd,e,_26);},triggerCacheRefresh:function(){Ext.dd.DDM.refreshCache(this.groups);}});
+
+Ext.data.SortTypes={none:function(s){return s;},stripTagsRE:/<\/?[^>]+>/gi,asText:function(s){return String(s).replace(this.stripTagsRE,"");},asUCText:function(s){return String(s).toUpperCase().replace(this.stripTagsRE,"");},asUCString:function(s){return String(s).toUpperCase();},asDate:function(s){if(!s){return 0;}if(s instanceof Date){return s.getTime();}return Date.parse(String(s));},asFloat:function(s){var _7=parseFloat(String(s).replace(/,/g,""));if(isNaN(_7)){_7=0;}return _7;},asInt:function(s){var _9=parseInt(String(s).replace(/,/g,""));if(isNaN(_9)){_9=0;}return _9;}};
+
+Ext.data.Record=function(_1,id){this.id=(id||id===0)?id:++Ext.data.Record.AUTO_ID;this.data=_1;};Ext.data.Record.create=function(o){var f=function(){f.superclass.constructor.apply(this,arguments);};Ext.extend(f,Ext.data.Record);var p=f.prototype;p.fields=new Ext.util.MixedCollection(false,function(_6){return _6.name;});for(var i=0,_8=o.length;i<_8;i++){p.fields.add(new Ext.data.Field(o[i]));}f.getField=function(_9){return p.fields.get(_9);};return f;};Ext.data.Record.AUTO_ID=1000;Ext.data.Record.EDIT="edit";Ext.data.Record.REJECT="reject";Ext.data.Record.COMMIT="commit";Ext.data.Record.prototype={dirty:false,editing:false,error:null,modified:null,join:function(_a){this.store=_a;},set:function(_b,_c){if(this.data[_b]==_c){return;}this.dirty=true;if(!this.modified){this.modified={};}if(typeof this.modified[_b]=="undefined"){this.modified[_b]=this.data[_b];}this.data[_b]=_c;if(!this.editing){this.store.afterEdit(this);}},get:function(_d){return this.data[_d];},beginEdit:function(){this.editing=true;this.modified={};},cancelEdit:function(){this.editing=false;delete this.modified;},endEdit:function(){this.editing=false;if(this.dirty&&this.store){this.store.afterEdit(this);}},reject:function(){var m=this.modified;for(var n in m){if(typeof m[n]!="function"){this.data[n]=m[n];}}this.dirty=false;delete this.modified;this.editing=false;if(this.store){this.store.afterReject(this);}},commit:function(){this.dirty=false;delete this.modified;this.editing=false;if(this.store){this.store.afterCommit(this);}},hasError:function(){return this.error!=null;},clearError:function(){this.error=null;}};
+
+Ext.data.Store=function(_1){this.data=new Ext.util.MixedCollection(false);this.data.getKey=function(o){return o.id;};this.baseParams={};this.paramNames={"start":"start","limit":"limit","sort":"sort","dir":"dir"};Ext.apply(this,_1);if(this.reader&&!this.recordType){this.recordType=this.reader.recordType;}this.fields=this.recordType.prototype.fields;this.modified=[];this.events={datachanged:true,add:true,remove:true,update:true,clear:true,beforeload:true,load:true,loadexception:true};if(this.proxy){this.relayEvents(this.proxy,["loadexception"]);}this.sortToggle={};Ext.data.Store.superclass.constructor.call(this);};Ext.extend(Ext.data.Store,Ext.util.Observable,{remoteSort:false,lastOptions:null,add:function(_3){_3=[].concat(_3);for(var i=0,_5=_3.length;i<_5;i++){_3[i].join(this);}var _6=this.data.length;this.data.addAll(_3);this.fireEvent("add",this,_3,_6);},remove:function(_7){var _8=this.data.indexOf(_7);this.data.removeAt(_8);this.fireEvent("remove",this,_7,_8);},removeAll:function(){this.data.clear();this.fireEvent("clear",this);},insert:function(_9,_a){_a=[].concat(_a);for(var i=0,_c=_a.length;i<_c;i++){this.data.insert(_9,_a[i]);_a[i].join(this);}this.fireEvent("add",this,_a,_9);},indexOf:function(_d){return this.data.indexOf(_d);},indexOfId:function(id){return this.data.indexOfKey(id);},getById:function(id){return this.data.key(id);},getAt:function(_10){return this.data.itemAt(_10);},getRange:function(_11,end){return this.data.getRange(_11,end);},storeOptions:function(o){o=Ext.apply({},o);delete o.callback;delete o.scope;this.lastOptions=o;},load:function(_14){_14=_14||{};if(this.fireEvent("beforeload",this,_14)!==false){this.storeOptions(_14);var p=Ext.apply(_14.params||{},this.baseParams);if(this.sortInfo&&this.remoteSort){var pn=this.paramNames;p[pn["sort"]]=this.sortInfo.field;p[pn["dir"]]=this.sortInfo.direction;}this.proxy.load(p,this.reader,this.loadRecords,this,_14);}},reload:function(_17){this.load(Ext.applyIf(_17||{},this.lastOptions));},loadRecords:function(o,_19,_1a){if(!o||_1a===false){if(_1a!==false){this.fireEvent("load",this,[],_19);}if(_19.callback){_19.callback.call(_19.scope||this,[],_19,false);}return;}var r=o.records,t=o.totalRecords||r.length;for(var i=0,len=r.length;i<len;i++){r[i].join(this);}if(!_19||_19.add!==true){this.data.clear();this.data.addAll(r);this.totalLength=t;this.applySort();this.fireEvent("datachanged",this);}else{this.totalLength=Math.max(t,this.data.length+r.length);this.data.addAll(r);}this.fireEvent("load",this,r,_19);if(_19.callback){_19.callback.call(_19.scope||this,r,_19,true);}},loadData:function(o,_20){var r=this.reader.readRecords(o);this.loadRecords(r,{add:_20},true);},getCount:function(){return this.data.length||0;},getTotalCount:function(){return this.totalLength||0;},getSortState:function(){return this.sortInfo;},applySort:function(){if(this.sortInfo&&!this.remoteSort){var s=this.sortInfo,f=s.field;var st=this.fields.get(f).sortType;var fn=function(r1,r2){var v1=st(r1.data[f]),v2=st(r2.data[f]);return v1>v2?1:(v1<v2?-1:0);};this.data.sort(s.direction,fn);if(this.snapshot&&this.snapshot!=this.data){this.snapshot.sort(s.direction,fn);}}},setDefaultSort:function(_2a,dir){this.sortInfo={field:_2a,direction:dir?dir.toUpperCase():"ASC"};},sort:function(_2c,dir){var f=this.fields.get(_2c);if(!dir){if(this.sortInfo&&this.sortInfo.field==f.name){dir=(this.sortToggle[f.name]||"ASC").toggle("ASC","DESC");}else{dir=f.sortDir;}}this.sortToggle[f.name]=dir;this.sortInfo={field:f.name,direction:dir};if(!this.remoteSort){this.applySort();this.fireEvent("datachanged",this);}else{this.load(this.lastOptions);}},each:function(fn,_30){this.data.each(fn,_30);},getModifiedRecords:function(){return this.modified;},filter:function(_31,_32){if(!_32.exec){_32=String(_32);if(_32.length==0){return this.clearFilter();}_32=new RegExp("^"+Ext.escapeRe(_32),"i");}this.filterBy(function(r){return _32.test(r.data[_31]);});},filterBy:function(fn,_35){var _36=this.snapshot||this.data;this.snapshot=_36;this.data=_36.filterBy(fn,_35);this.fireEvent("datachanged",this);},clearFilter:function(){if(this.snapshot&&this.snapshot!=this.data){this.data=this.snapshot;delete this.snapshot;this.fireEvent("datachanged",this);}},afterEdit:function(_37){if(this.modified.indexOf(_37)==-1){this.modified.push(_37);}this.fireEvent("update",this,_37,Ext.data.Record.EDIT);},afterReject:function(_38){this.modified.remove(_38);this.fireEvent("update",this,_38,Ext.data.Record.REJECT);},afterCommit:function(_39){this.modified.remove(_39);this.fireEvent("update",this,_39,Ext.data.Record.COMMIT);},commitChanges:function(){var m=this.modified.slice(0);this.modified=[];for(var i=0,len=m.length;i<len;i++){m[i].commit();}},rejectChanges:function(){var m=this.modified.slice(0);this.modified=[];for(var i=0,len=m.length;i<len;i++){m[i].reject();}}});
+
+Ext.data.SimpleStore=function(_1){Ext.data.SimpleStore.superclass.constructor.call(this,{reader:new Ext.data.ArrayReader({id:_1.id},Ext.data.Record.create(_1.fields)),proxy:new Ext.data.MemoryProxy(_1.data)});this.load();};Ext.extend(Ext.data.SimpleStore,Ext.data.Store);
+
+Ext.data.Connection=function(_1){Ext.apply(this,_1);this.events={"beforerequest":true,"requestcomplete":true,"requestexception":true};Ext.data.Connection.superclass.constructor.call(this);};Ext.extend(Ext.data.Connection,Ext.util.Observable,{timeout:30000,request:function(_2){if(this.fireEvent("beforerequest",this,_2)!==false){var p=_2.params;if(typeof p=="object"){p=Ext.urlEncode(Ext.apply(_2.params,this.extraParams));}var cb={success:this.handleResponse,failure:this.handleFailure,scope:this,argument:{options:_2},timeout:this.timeout};var _5=_2.method||this.method||(p?"POST":"GET");var _6=_2.url||this.url;if(this.autoAbort!==false){this.abort();}if(_5=="GET"&&p){_6+=(_6.indexOf("?")!=-1?"&":"?")+p;p="";}this.transId=Ext.lib.Ajax.request(_5,_6,cb,p);}else{if(typeof _2.callback=="function"){_2.callback.call(_2.scope||window,_2,null,null);}}},isLoading:function(){return this.transId?true:false;},abort:function(){if(this.isLoading()){Ext.lib.Ajax.abort(this.transId);}},handleResponse:function(_7){this.transId=false;var _8=_7.argument.options;this.fireEvent("requestcomplete",this,_7,_8);if(typeof _8.callback=="function"){_8.callback.call(_8.scope||window,_8,true,_7);}},handleFailure:function(_9,e){this.transId=false;var _b=_9.argument.options;this.fireEvent("requestexception",this,_9,_b,e);if(typeof _b.callback=="function"){_b.callback.call(_b.scope||window,_b,false,_9);}}});
+
+Ext.data.Field=function(_1){if(typeof _1=="string"){_1={name:_1};}Ext.apply(this,_1);if(!this.type){this.type="auto";}var st=Ext.data.SortTypes;if(typeof this.sortType=="string"){this.sortType=st[this.sortType];}if(!this.sortType){switch(this.type){case "string":this.sortType=st.asUCString;break;case "date":this.sortType=st.asDate;break;default:this.sortType=st.none;}}var _3=/[\$,%]/g;if(!this.convert){var cv,_5=this.dateFormat;switch(this.type){case "":case "auto":case undefined:cv=function(v){return v;};break;case "string":cv=function(v){return String(v);};break;case "int":cv=function(v){return v!==undefined&&v!==null&&v!==""?parseInt(String(v).replace(_3,""),10):"";};break;case "float":cv=function(v){return v!==undefined&&v!==null&&v!==""?parseFloat(String(v).replace(_3,""),10):"";};break;case "bool":case "boolean":cv=function(v){return v===true||v==="true"||v==1;};break;case "date":cv=function(v){if(!v){return "";}if(v instanceof Date){return v;}if(_5){if(_5=="timestamp"){return new Date(v*1000);}return Date.parseDate(v,_5);}var _c=Date.parse(v);return _c?new Date(_c):null;};break;}this.convert=cv;}};Ext.data.Field.prototype={dateFormat:null,defaultValue:"",mapping:null,sortType:null,sortDir:"ASC"};
+
+Ext.data.DataReader=function(_1,_2){this.meta=_1;this.recordType=_2 instanceof Array?Ext.data.Record.create(_2):_2;};Ext.data.DataReader.prototype={};
+
+Ext.data.DataProxy=function(){this.events={beforeload:true,load:true,loadexception:true};Ext.data.DataProxy.superclass.constructor.call(this);};Ext.extend(Ext.data.DataProxy,Ext.util.Observable);
+
+Ext.data.MemoryProxy=function(_1){Ext.data.MemoryProxy.superclass.constructor.call(this);this.data=_1;};Ext.extend(Ext.data.MemoryProxy,Ext.data.DataProxy,{load:function(_2,_3,_4,_5,_6){_2=_2||{};var _7;try{_7=_3.readRecords(this.data);}catch(e){this.fireEvent("loadexception",this,_6,null,e);_4.call(_5,null,_6,false);return;}_4.call(_5,_7,_6,true);},update:function(_8,_9){}});
+
+Ext.data.HttpProxy=function(_1){Ext.data.HttpProxy.superclass.constructor.call(this);this.conn=_1.events?_1:new Ext.data.Connection(_1);};Ext.extend(Ext.data.HttpProxy,Ext.data.DataProxy,{getConnection:function(){return this.conn;},load:function(_2,_3,_4,_5,_6){if(this.fireEvent("beforeload",this,_2)!==false){this.conn.request({params:_2||{},request:{callback:_4,scope:_5,arg:_6},reader:_3,callback:this.loadResponse,scope:this});}else{_4.call(_5||this,null,_6,false);}},loadResponse:function(o,_8,_9){if(!_8){this.fireEvent("loadexception",this,o,_9);o.request.callback.call(o.request.scope,null,o.request.arg,false);return;}var _a;try{_a=o.reader.read(_9);}catch(e){this.fireEvent("loadexception",this,o,_9,e);o.request.callback.call(o.request.scope,null,o.request.arg,false);return;}this.fireEvent("load",this,o,o.request.arg);o.request.callback.call(o.request.scope,_a,o.request.arg,true);},update:function(_b){},updateResponse:function(_c){}});
+
+Ext.data.ScriptTagProxy=function(_1){Ext.data.ScriptTagProxy.superclass.constructor.call(this);Ext.apply(this,_1);this.head=document.getElementsByTagName("head")[0];};Ext.data.ScriptTagProxy.TRANS_ID=1000;Ext.extend(Ext.data.ScriptTagProxy,Ext.data.DataProxy,{timeout:30000,callbackParam:"callback",nocache:true,load:function(_2,_3,_4,_5,_6){if(this.fireEvent("beforeload",this,_2)!==false){var p=Ext.urlEncode(Ext.apply(_2,this.extraParams));var _8=this.url;_8+=(_8.indexOf("?")!=-1?"&":"?")+p;if(this.nocache){_8+="&_dc="+(new Date().getTime());}var _9=++Ext.data.ScriptTagProxy.TRANS_ID;var _a={id:_9,cb:"stcCallback"+_9,scriptId:"stcScript"+_9,params:_2,arg:_6,url:_8,callback:_4,scope:_5,reader:_3};var _b=this;window[_a.cb]=function(o){_b.handleResponse(o,_a);};_8+=String.format("&{0}={1}",this.callbackParam,_a.cb);if(this.autoAbort!==false){this.abort();}_a.timeoutId=this.handleFailure.defer(this.timeout,this,[_a]);var _d=document.createElement("script");_d.setAttribute("src",_8);_d.setAttribute("type","text/javascript");_d.setAttribute("id",_a.scriptId);this.head.appendChild(_d);this.trans=_a;}else{_4.call(_5||this,null,_6,false);}},isLoading:function(){return this.trans?true:false;},abort:function(){if(this.isLoading()){this.destroyTrans(this.trans);}},destroyTrans:function(_e,_f){this.head.removeChild(document.getElementById(_e.scriptId));clearTimeout(_e.timeoutId);if(_f){window[_e.cb]=undefined;try{delete window[_e.cb];}catch(e){}}else{window[_e.cb]=function(){window[_e.cb]=undefined;try{delete window[_e.cb];}catch(e){}};}},handleResponse:function(o,_11){this.trans=false;this.destroyTrans(_11,true);var _12;try{_12=_11.reader.readRecords(o);}catch(e){this.fireEvent("loadexception",this,o,_11.arg,e);_11.callback.call(_11.scope||window,null,_11.arg,false);return;}this.fireEvent("load",this,o,_11.arg);_11.callback.call(_11.scope||window,_12,_11.arg,true);},handleFailure:function(_13){this.trans=false;this.destroyTrans(_13,false);this.fireEvent("loadexception",this,null,_13.arg);_13.callback.call(_13.scope||window,null,_13.arg,false);}});
+
+Ext.data.JsonReader=function(_1,_2){Ext.data.JsonReader.superclass.constructor.call(this,_1,_2);};Ext.extend(Ext.data.JsonReader,Ext.data.DataReader,{read:function(_3){var _4=_3.responseText;var o=eval("("+_4+")");if(!o){throw {message:"JsonReader.read: Json object not found"};}return this.readRecords(o);},simpleAccess:function(_6,_7){return _6[_7];},getJsonAccessor:function(){var re=/[\[\.]/;return function(_9){try{return (re.test(_9))?new Function("obj","return obj."+_9):function(_a){return _a[_9];};}catch(e){}return Ext.emptyFn;};}(),readRecords:function(o){this.jsonData=o;var s=this.meta,_d=this.recordType,f=_d.prototype.fields,fi=f.items,fl=f.length;if(!this.ef){if(s.totalProperty){this.getTotal=this.getJsonAccessor(s.totalProperty);}if(s.successProperty){this.getSuccess=this.getJsonAccessor(s.successProperty);}this.getRoot=s.root?this.getJsonAccessor(s.root):function(p){return p;};if(s.id){var g=this.getJsonAccessor(s.id);this.getId=function(rec){var r=g(rec);return (r===undefined||r==="")?null:r;};}else{this.getId=function(){return null;};}this.ef=[];for(var i=0;i<fl;i++){f=fi[i];var map=(f.mapping!==undefined&&f.mapping!==null)?f.mapping:f.name;this.ef[i]=this.getJsonAccessor(map);}}var _17=this.getRoot(o),c=_17.length,_19=c,_1a=true;if(s.totalProperty){var v=parseInt(this.getTotal(o),10);if(!isNaN(v)){_19=v;}}if(s.successProperty){var v=this.getSuccess(o);if(v===false||v==="false"){_1a=false;}}var _1c=[];for(var i=0;i<c;i++){var n=_17[i];var _1e={};var id=this.getId(n);for(var j=0;j<fl;j++){f=fi[j];var v=this.ef[j](n);_1e[f.name]=f.convert((v!==undefined)?v:f.defaultValue);}var _21=new _d(_1e,id);_21.json=n;_1c[i]=_21;}return {success:_1a,records:_1c,totalRecords:_19};}});
+
+Ext.data.XmlReader=function(_1,_2){Ext.data.XmlReader.superclass.constructor.call(this,_1,_2);};Ext.extend(Ext.data.XmlReader,Ext.data.DataReader,{read:function(_3){var _4=_3.responseXML;if(!_4){throw {message:"XmlReader.read: XML Document not available"};}return this.readRecords(_4);},readRecords:function(_5){this.xmlData=_5;var _6=_5.documentElement||_5;var q=Ext.DomQuery;var _8=this.recordType,_9=_8.prototype.fields;var _a=this.meta.id;var _b=0,_c=true;if(this.meta.totalRecords){_b=q.selectNumber(this.meta.totalRecords,_6,0);}if(this.meta.success){var sv=q.selectValue(this.meta.success,_6,true);_c=sv!==false&&sv!=="false";}var _e=[];var ns=q.select(this.meta.record,_6);for(var i=0,len=ns.length;i<len;i++){var n=ns[i];var _13={};var id=_a?q.selectValue(_a,n):undefined;for(var j=0,_16=_9.length;j<_16;j++){var f=_9.items[j];var v=q.selectValue(f.mapping||f.name,n,f.defaultValue);v=f.convert(v);_13[f.name]=v;}var _19=new _8(_13,id);_19.node=n;_e[_e.length]=_19;}return {success:_c,records:_e,totalRecords:_b||_e.length};}});
+
+Ext.data.ArrayReader=function(_1,_2){Ext.data.ArrayReader.superclass.constructor.call(this,_1,_2);};Ext.extend(Ext.data.ArrayReader,Ext.data.JsonReader,{readRecords:function(o){var _4=this.meta?this.meta.id:null;var _5=this.recordType,_6=_5.prototype.fields;var _7=[];var _8=o;for(var i=0;i<_8.length;i++){var n=_8[i];var _b={};var id=((_4||_4===0)&&n[_4]!==undefined&&n[_4]!==""?n[_4]:null);for(var j=0,_e=_6.length;j<_e;j++){var f=_6.items[j];var k=f.mapping!==undefined&&f.mapping!==null?f.mapping:j;var v=n[k]!==undefined?n[k]:f.defaultValue;v=f.convert(v);_b[f.name]=v;}var _12=new _5(_b,id);_12.json=n;_7[_7.length]=_12;}return {records:_7,totalRecords:_7.length};}});
+
+Ext.data.Tree=function(_1){this.nodeHash={};this.root=null;if(_1){this.setRootNode(_1);}this.events={"append":true,"remove":true,"move":true,"insert":true,"beforeappend":true,"beforeremove":true,"beforemove":true,"beforeinsert":true};Ext.data.Tree.superclass.constructor.call(this);};Ext.extend(Ext.data.Tree,Ext.util.Observable,{pathSeparator:"/",getRootNode:function(){return this.root;},setRootNode:function(_2){this.root=_2;_2.ownerTree=this;_2.isRoot=true;this.registerNode(_2);return _2;},getNodeById:function(id){return this.nodeHash[id];},registerNode:function(_4){this.nodeHash[_4.id]=_4;},unregisterNode:function(_5){delete this.nodeHash[_5.id];},toString:function(){return "[Tree"+(this.id?" "+this.id:"")+"]";}});Ext.data.Node=function(_6){this.attributes=_6||{};this.leaf=this.attributes.leaf;this.id=this.attributes.id;if(!this.id){this.id=Ext.id(null,"ynode-");this.attributes.id=this.id;}this.childNodes=[];if(!this.childNodes.indexOf){this.childNodes.indexOf=function(o){for(var i=0,_9=this.length;i<_9;i++){if(this[i]==o){return i;}}return -1;};}this.parentNode=null;this.firstChild=null;this.lastChild=null;this.previousSibling=null;this.nextSibling=null;this.events={"append":true,"remove":true,"move":true,"insert":true,"beforeappend":true,"beforeremove":true,"beforemove":true,"beforeinsert":true};this.listeners=this.attributes.listeners;Ext.data.Node.superclass.constructor.call(this);};Ext.extend(Ext.data.Node,Ext.util.Observable,{fireEvent:function(_a){if(Ext.data.Node.superclass.fireEvent.apply(this,arguments)===false){return false;}var ot=this.getOwnerTree();if(ot){if(ot.fireEvent.apply(this.ownerTree,arguments)===false){return false;}}return true;},isLeaf:function(){return this.leaf===true;},setFirstChild:function(_c){this.firstChild=_c;},setLastChild:function(_d){this.lastChild=_d;},isLast:function(){return (!this.parentNode?true:this.parentNode.lastChild==this);},isFirst:function(){return (!this.parentNode?true:this.parentNode.firstChild==this);},hasChildNodes:function(){return !this.isLeaf()&&this.childNodes.length>0;},appendChild:function(_e){var _f=false;if(_e instanceof Array){_f=_e;}else{if(arguments.length>1){_f=arguments;}}if(_f){for(var i=0,len=_f.length;i<len;i++){this.appendChild(_f[i]);}}else{if(this.fireEvent("beforeappend",this.ownerTree,this,_e)===false){return false;}var _12=this.childNodes.length;var _13=_e.parentNode;if(_13){if(_e.fireEvent("beforemove",_e.getOwnerTree(),_e,_13,this,_12)===false){return false;}_13.removeChild(_e);}_12=this.childNodes.length;if(_12==0){this.setFirstChild(_e);}this.childNodes.push(_e);_e.parentNode=this;var ps=this.childNodes[_12-1];if(ps){_e.previousSibling=ps;ps.nextSibling=_e;}else{_e.previousSibling=null;}_e.nextSibling=null;this.setLastChild(_e);_e.setOwnerTree(this.getOwnerTree());this.fireEvent("append",this.ownerTree,this,_e,_12);if(_13){_e.fireEvent("move",this.ownerTree,_e,_13,this,_12);}return _e;}},removeChild:function(_15){var _16=this.childNodes.indexOf(_15);if(_16==-1){return false;}if(this.fireEvent("beforeremove",this.ownerTree,this,_15)===false){return false;}this.childNodes.splice(_16,1);if(_15.previousSibling){_15.previousSibling.nextSibling=_15.nextSibling;}if(_15.nextSibling){_15.nextSibling.previousSibling=_15.previousSibling;}if(this.firstChild==_15){this.setFirstChild(_15.nextSibling);}if(this.lastChild==_15){this.setLastChild(_15.previousSibling);}_15.setOwnerTree(null);_15.parentNode=null;_15.previousSibling=null;_15.nextSibling=null;this.fireEvent("remove",this.ownerTree,this,_15);return _15;},insertBefore:function(_17,_18){if(!_18){return this.appendChild(_17);}if(_17==_18){return false;}if(this.fireEvent("beforeinsert",this.ownerTree,this,_17,_18)===false){return false;}var _19=this.childNodes.indexOf(_18);var _1a=_17.parentNode;var _1b=_19;if(_1a==this&&this.childNodes.indexOf(_17)<_19){_1b--;}if(_1a){if(_17.fireEvent("beforemove",_17.getOwnerTree(),_17,_1a,this,_19,_18)===false){return false;}_1a.removeChild(_17);}if(_1b==0){this.setFirstChild(_17);}this.childNodes.splice(_1b,0,_17);_17.parentNode=this;var ps=this.childNodes[_1b-1];if(ps){_17.previousSibling=ps;ps.nextSibling=_17;}else{_17.previousSibling=null;}_17.nextSibling=_18;_18.previousSibling=_17;_17.setOwnerTree(this.getOwnerTree());this.fireEvent("insert",this.ownerTree,this,_17,_18);if(_1a){_17.fireEvent("move",this.ownerTree,_17,_1a,this,_1b,_18);}return _17;},item:function(_1d){return this.childNodes[_1d];},replaceChild:function(_1e,_1f){this.insertBefore(_1e,_1f);this.removeChild(_1f);return _1f;},indexOf:function(_20){return this.childNodes.indexOf(_20);},getOwnerTree:function(){if(!this.ownerTree){var p=this;while(p){if(p.ownerTree){this.ownerTree=p.ownerTree;break;}p=p.parentNode;}}return this.ownerTree;},getDepth:function(){var _22=0;var p=this;while(p.parentNode){++_22;p=p.parentNode;}return _22;},setOwnerTree:function(_24){if(_24!=this.ownerTree){if(this.ownerTree){this.ownerTree.unregisterNode(this);}this.ownerTree=_24;var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].setOwnerTree(_24);}if(_24){_24.registerNode(this);}}},getPath:function(_28){_28=_28||"id";var p=this.parentNode;var b=[this.attributes[_28]];while(p){b.unshift(p.attributes[_28]);p=p.parentNode;}var sep=this.getOwnerTree().pathSeparator;return sep+b.join(sep);},bubble:function(fn,_2d,_2e){var p=this;while(p){if(fn.call(_2d||p,_2e||p)===false){break;}p=p.parentNode;}},cascade:function(fn,_31,_32){if(fn.call(_31||this,_32||this)!==false){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].cascade(fn,_31,_32);}}},eachChild:function(fn,_37,_38){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){if(fn.call(_37||this,_38||cs[i])===false){break;}}},findChild:function(_3c,_3d){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){if(cs[i].attributes[_3c]==_3d){return cs[i];}}return null;},findChildBy:function(fn,_42){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){if(fn.call(_42||cs[i],cs[i])===true){return cs[i];}}return null;},sort:function(fn,_47){var cs=this.childNodes;var len=cs.length;if(len>0){var _4a=_47?function(){fn.apply(_47,arguments);}:fn;cs.sort(_4a);for(var i=0;i<len;i++){var n=cs[i];n.previousSibling=cs[i-1];n.nextSibling=cs[i+1];if(i==0){this.setFirstChild(n);}if(i==len-1){this.setLastChild(n);}}}},contains:function(_4d){return _4d.isAncestor(this);},isAncestor:function(_4e){var p=this.parentNode;while(p){if(p==_4e){return true;}p=p.parentNode;}return false;},toString:function(){return "[Node"+(this.id?" "+this.id:"")+"]";}});
+
+Ext.ComponentMgr=function(){var _1=new Ext.util.MixedCollection();return {register:function(c){_1.add(c);},unregister:function(c){_1.remove(c);},get:function(id){return _1.get(id);},onAvailable:function(id,fn,_7){_1.on("add",function(_8,o){if(o.id==id){fn.call(_7||o,o);_1.un("add",fn,_7);}});}};}();Ext.Component=function(_a){_a=_a||{};if(_a.tagName||_a.dom||typeof _a=="string"){_a={el:_a,id:_a.id||_a};}Ext.apply(this,_a);this.addEvents({disable:true,enable:true,beforeshow:true,show:true,beforehide:true,hide:true,beforerender:true,render:true,beforedestroy:true,destroy:true});if(!this.id){this.id="ext-comp-"+(++Ext.Component.AUTO_ID);}Ext.ComponentMgr.register(this);Ext.Component.superclass.constructor.call(this);};Ext.Component.AUTO_ID=1000;Ext.extend(Ext.Component,Ext.util.Observable,{hidden:false,disabled:false,disabledClass:"x-item-disabled",rendered:false,ctype:"Ext.Component",actionMode:"el",getActionEl:function(){return this[this.actionMode];},render:function(_b){if(!this.rendered&&this.fireEvent("beforerender",this)!==false){this.container=Ext.get(_b);this.rendered=true;this.onRender(this.container);if(this.cls){this.el.addClass(this.cls);delete this.cls;}this.fireEvent("render",this);if(this.hidden){this.hide();}if(this.disabled){this.disable();}this.afterRender(this.container);}},onRender:function(ct){this.el=Ext.get(this.el);ct.dom.appendChild(this.el.dom);},getAutoCreate:function(){var _d=typeof this.autoCreate=="object"?this.autoCreate:Ext.apply({},this.defaultAutoCreate);if(this.id&&!_d.id){_d.id=this.id;}return _d;},afterRender:Ext.emptyFn,destroy:function(){if(this.fireEvent("beforedestroy",this)!==false){this.purgeListeners();if(this.rendered){this.el.removeAllListeners();this.el.remove();if(this.actionMode=="container"){this.container.remove();}}this.onDestroy();Ext.ComponentMgr.unregister(this);this.fireEvent("destroy",this);}},onDestroy:function(){},getEl:function(){return this.el;},focus:function(_e){if(this.rendered){this.el.focus();if(_e===true){this.el.dom.select();}}},blur:function(){if(this.rendered){this.el.blur();}},disable:function(){if(this.rendered){this.getActionEl().addClass(this.disabledClass);this.el.dom.disabled=true;}this.disabled=true;this.fireEvent("disable",this);},enable:function(){if(this.rendered){this.getActionEl().removeClass(this.disabledClass);this.el.dom.disabled=false;}this.disabled=false;this.fireEvent("enable",this);},setDisabled:function(_f){this[_f?"disable":"enable"]();},show:function(){if(this.fireEvent("beforeshow",this)!==false){this.hidden=false;if(this.rendered){this.onShow();}this.fireEvent("show",this);}},onShow:function(){var st=this.getActionEl().dom.style;st.display="";st.visibility="visible";},hide:function(){if(this.fireEvent("beforehide",this)!==false){this.hidden=true;if(this.rendered){this.onHide();}this.fireEvent("hide",this);}},onHide:function(){this.getActionEl().dom.style.display="none";},setVisible:function(_11){if(_11){this.show();}else{this.hide();}}});
+
+(function(){Ext.Layer=function(_1,_2){_1=_1||{};var dh=Ext.DomHelper;var cp=_1.parentEl,_5=cp?Ext.getDom(cp):document.body;if(_2){this.dom=Ext.getDom(_2);}if(!this.dom){var o=_1.dh||{tag:"div",cls:"x-layer"};this.dom=dh.append(_5,o);}if(_1.cls){this.addClass(_1.cls);}this.constrain=_1.constrain!==false;this.visibilityMode=Ext.Element.VISIBILITY;if(_1.id){this.id=this.dom.id=_1.id;}else{this.id=Ext.id(this.dom);}var _7=(_1.zindex||parseInt(this.getStyle("z-index"),10))||11000;this.position("absolute",_7);if(_1.shadow){this.shadowOffset=_1.shadowOffset||4;this.shadow=new Ext.Shadow({offset:this.shadowOffset,mode:_1.shadow});}else{this.shadowOffset=0;}if(_1.shim!==false&&Ext.useShims){this.shim=this.createShim();this.shim.setOpacity(0);this.shim.position("absolute",_7-2);}this.useDisplay=_1.useDisplay;this.hide();};var _8=Ext.Element.prototype;Ext.extend(Ext.Layer,Ext.Element,{sync:function(_9){var sw=this.shadow,sh=this.shim;if(!this.updating&&this.isVisible()&&(sw||sh)){var w=this.getWidth(),h=this.getHeight();var l=this.getLeft(true),t=this.getTop(true);if(sw){if(_9&&!sw.isVisible()){sw.show(this);}else{sw.realign(l,t,w,h);}if(sh){if(_9){sh.show();}var a=sw.adjusts,s=sh.dom.style;s.left=(l+a.l)+"px";s.top=(t+a.t)+"px";s.width=(w+a.w)+"px";s.height=(h+a.h)+"px";}}else{if(sh){if(_9){sh.show();}sh.setSize(w,h);sh.setLeftTop(l,t);}}}},destroy:function(){if(this.shim){this.shim.remove();}if(this.shadow){this.shadow.hide();}this.removeAllListeners();this.remove();},beginUpdate:function(){this.updating=true;},endUpdate:function(){this.updating=false;this.sync(true);},hideUnders:function(_12){if(this.shadow){this.shadow.hide();}if(this.shim){this.shim.hide();if(_12){this.shim.setLeftTop(-10000,-10000);}}},constrainXY:function(){if(this.constrain){var vw=Ext.lib.Dom.getViewWidth(),vh=Ext.lib.Dom.getViewHeight();var s=Ext.get(document).getScroll();xy=this.getXY();var x=xy[0],y=xy[1];var w=this.dom.offsetWidth+this.shadowOffset,h=this.dom.offsetHeight+this.shadowOffset;var _1a=false;if((x+w)>vw+s.left){x=vw-w-this.shadowOffset;_1a=true;}if((y+h)>vh+s.top){y=vh-h-this.shadowOffset;_1a=true;}if(x<s.left){x=s.left;_1a=true;}if(y<s.top){y=s.top;_1a=true;}if(_1a){if(this.avoidY){var ay=this.avoidY;if(y<=ay&&(y+h)>=ay){y=ay-h-5;}}xy=[x,y];this.lastXY=xy;_8.setXY.call(this,xy);this.sync();}}},showAction:function(){if(this.useDisplay===true){this.setDisplayed("");}else{if(this.lastXY){_8.setXY.call(this,this.lastXY);}}},hideAction:function(){if(this.useDisplay===true){this.setDisplayed(false);}else{this.setLeftTop(-10000,-10000);}},setVisible:function(v,a,d,c,e){this.showAction();if(a&&v){var cb=function(){this.sync(true);if(c){c();}}.createDelegate(this);_8.setVisible.call(this,true,true,d,cb,e);}else{if(!v){this.hideUnders(true);}var cb=c;if(a){cb=function(){this.hideAction();if(c){c();}}.createDelegate(this);}_8.setVisible.call(this,v,a,d,cb,e);if(v){this.sync(true);}else{if(!a){this.hideAction();}}}},beforeFx:function(){this.beforeAction();return Ext.Layer.superclass.beforeFx.apply(this,arguments);},afterFx:function(){Ext.Layer.superclass.afterFx.apply(this,arguments);this.sync(this.isVisible());},beforeAction:function(){if(!this.updating&&this.shadow){this.shadow.hide();}},setXY:function(xy,a,d,c,e){this.fixDisplay();this.beforeAction();this.lastXY=xy;var cb=this.createCB(c);_8.setXY.call(this,xy,a,d,cb,e);if(!a){cb();}},createCB:function(c){var el=this;return function(){el.constrainXY();el.sync(true);if(c){c();}};},setX:function(x,a,d,c,e){this.setXY([x,this.getY()],a,d,c,e);},setY:function(y,a,d,c,e){this.setXY([this.getX(),y],a,d,c,e);},setSize:function(w,h,a,d,c,e){this.beforeAction();var cb=this.createCB(c);_8.setSize.call(this,w,h,a,d,cb,e);if(!a){cb();}},setWidth:function(w,a,d,c,e){this.beforeAction();var cb=this.createCB(c);_8.setWidth.call(this,w,a,d,cb,e);if(!a){cb();}},setHeight:function(h,a,d,c,e){this.beforeAction();var cb=this.createCB(c);_8.setHeight.call(this,h,a,d,cb,e);if(!a){cb();}},setBounds:function(x,y,w,h,a,d,c,e){this.beforeAction();var cb=this.createCB(c);if(!a){_8.setXY.call(this,[x,y]);_8.setSize.call(this,w,h,a,d,cb,e);cb();}else{_8.setBounds.call(this,x,y,w,h,a,d,cb,e);}return this;},setZIndex:function(_50){this.setStyle("z-index",_50+2);if(this.shadow){this.shadow.setZIndex(_50+1);}if(this.shim){this.shim.setStyle("z-index",_50);}}});})();
+
+Ext.Shadow=function(_1){Ext.apply(this,_1);if(typeof this.mode!="string"){this.mode=this.defaultMode;}var o=this.offset,a={h:0};switch(this.mode.toLowerCase()){case "drop":a.w=0;a.l=a.t=o;break;case "sides":a.w=(o*2);a.l=-o;a.t=o;break;case "frame":a.w=a.h=(o*2);a.l=a.t=-o;break;}this.adjusts=a;};Ext.Shadow.prototype={offset:4,defaultMode:"drop",show:function(_4){_4=Ext.get(_4);if(!this.el){this.el=Ext.Shadow.Pool.pull();if(this.el.dom.nextSibling!=_4.dom){this.el.insertBefore(_4);}}this.el.setStyle("z-index",this.zIndex||parseInt(_4.getStyle("z-index"),10)-1);this.realign(_4.getLeft(true),_4.getTop(true),_4.getWidth(),_4.getHeight());this.el.dom.style.display="block";},isVisible:function(){return this.el?true:false;},realign:function(l,t,w,h){var a=this.adjusts,d=this.el.dom,s=d.style;s.left=(l+a.l)+"px";s.top=(t+a.t)+"px";var sw=(w+a.w),sh=(h+a.h),_e=sw+"px",_f=sh+"px";if(s.width!=_e||s.height!=_f){s.width=_e;s.height=_f;var cn=d.childNodes;var sww=Math.max(0,(sw-12))+"px";cn[0].childNodes[1].style.width=sww;cn[1].childNodes[1].style.width=sww;cn[2].childNodes[1].style.width=sww;cn[1].style.height=Math.max(0,(sh-12))+"px";}},hide:function(){if(this.el){this.el.dom.style.display="none";Ext.Shadow.Pool.push(this.el);delete this.el;}},setZIndex:function(z){this.zIndex=z;if(this.el){this.el.setStyle("z-index",z);}}};Ext.Shadow.Pool=function(){var p=[];var _14="<div class=\"x-shadow\"><div class=\"xst\"><div class=\"xstl\"></div><div class=\"xstc\"></div><div class=\"xstr\"></div></div><div class=\"xsc\"><div class=\"xsml\"></div><div class=\"xsmc\"></div><div class=\"xsmr\"></div></div><div class=\"xsb\"><div class=\"xsbl\"></div><div class=\"xsbc\"></div><div class=\"xsbr\"></div></div></div>";return {pull:function(){var sh=p.shift();if(!sh){sh=Ext.get(Ext.DomHelper.insertHtml("beforeBegin",document.body.firstChild,_14));if(Ext.isIE&&!Ext.isIE7){sh.setOpacity(0.3);}}return sh;},push:function(sh){p.push(sh);}};}();
+
+Ext.View=function(_1,_2,_3){this.el=Ext.get(_1,true);if(typeof _2=="string"){_2=new Ext.Template(_2);}_2.compile();this.tpl=_2;Ext.apply(this,_3);this.events={"beforeclick":true,"click":true,"dblclick":true,"contextmenu":true,"selectionchange":true,"beforeselect":true};this.el.on({"click":this.onClick,"dblclick":this.onDblClick,"contextmenu":this.onContextMenu,scope:this});this.selections=[];this.nodes=[];this.cmp=new Ext.CompositeElementLite([]);if(this.store){this.setStore(this.store,true);}Ext.View.superclass.constructor.call(this);};Ext.extend(Ext.View,Ext.util.Observable,{selectedClass:"x-view-selected",emptyText:"",getEl:function(){return this.el;},refresh:function(){var t=this.tpl;this.clearSelections();this.el.update("");var _5=[];var _6=this.store.getRange();if(_6.length<1){this.el.update(this.emptyText);return;}for(var i=0,_8=_6.length;i<_8;i++){var _9=this.prepareData(_6[i].data,i,_6[i]);_5[_5.length]=t.apply(_9);}this.el.update(_5.join(""));this.nodes=this.el.dom.childNodes;this.updateIndexes(0);},prepareData:function(_a,_b){return _a;},onUpdate:function(ds,_d){this.clearSelections();var _e=this.store.indexOf(_d);var n=this.nodes[_e];this.tpl.insertBefore(n,this.prepareData(_d.data));n.parentNode.removeChild(n);this.updateIndexes(_e,_e);},onAdd:function(ds,_11,_12){this.clearSelections();if(this.nodes.length==0){this.refresh();return;}var n=this.nodes[_12];for(var i=0,len=_11.length;i<len;i++){var d=this.prepareData(_11[i].data);if(n){this.tpl.insertBefore(n,d);}else{this.tpl.append(this.el,d);}}this.updateIndexes(_12);},onRemove:function(ds,_18,_19){this.clearSelections();this.el.dom.removeChild(this.nodes[_19]);this.updateIndexes(_19);},refreshNode:function(_1a){this.onUpdate(this.store,this.store.getAt(_1a));},updateIndexes:function(_1b,_1c){var ns=this.nodes;_1b=_1b||0;_1c=_1c||ns.length-1;for(var i=_1b;i<=_1c;i++){ns[i].nodeIndex=i;}},setStore:function(_1f,_20){if(!_20&&this.store){this.store.un("datachanged",this.refresh);this.store.un("add",this.onAdd);this.store.un("remove",this.onRemove);this.store.un("update",this.onUpdate);this.store.un("clear",this.refresh);}if(_1f){_1f.on("datachanged",this.refresh,this);_1f.on("add",this.onAdd,this);_1f.on("remove",this.onRemove,this);_1f.on("update",this.onUpdate,this);_1f.on("clear",this.refresh,this);}this.store=_1f;this.refresh();},findItemFromChild:function(_21){var el=this.el.dom;if(!_21||_21.parentNode==el){return _21;}var p=_21.parentNode;while(p&&p!=el){if(p.parentNode==el){return p;}p=p.parentNode;}return null;},onClick:function(e){var _25=this.findItemFromChild(e.getTarget());if(_25){var _26=this.indexOf(_25);if(this.onItemClick(_25,_26,e)!==false){this.fireEvent("click",this,_26,_25,e);}}else{this.clearSelections();}},onContextMenu:function(e){var _28=this.findItemFromChild(e.getTarget());if(_28){this.fireEvent("contextmenu",this,this.indexOf(_28),_28,e);}},onDblClick:function(e){var _2a=this.findItemFromChild(e.getTarget());if(_2a){this.fireEvent("dblclick",this,this.indexOf(_2a),_2a,e);}},onItemClick:function(_2b,_2c,e){if(this.fireEvent("beforeclick",this,_2c,_2b,e)===false){return false;}if(this.multiSelect||this.singleSelect){if(this.multiSelect&&e.shiftKey&&this.lastSelection){this.select(this.getNodes(this.indexOf(this.lastSelection),_2c),false);}else{this.select(_2b,this.multiSelect&&e.ctrlKey);this.lastSelection=_2b;}e.preventDefault();}return true;},getSelectionCount:function(){return this.selections.length;},getSelectedNodes:function(){return this.selections;},getSelectedIndexes:function(){var _2e=[],s=this.selections;for(var i=0,len=s.length;i<len;i++){_2e.push(s[i].nodeIndex);}return _2e;},clearSelections:function(_32){if(this.nodes&&(this.multiSelect||this.singleSelect)&&this.selections.length>0){this.cmp.elements=this.selections;this.cmp.removeClass(this.selectedClass);this.selections=[];if(!_32){this.fireEvent("selectionchange",this,this.selections);}}},isSelected:function(_33){var s=this.selections;if(s.length<1){return false;}_33=this.getNode(_33);return s.indexOf(_33)!==-1;},select:function(_35,_36,_37){if(_35 instanceof Array){if(!_36){this.clearSelections(true);}for(var i=0,len=_35.length;i<len;i++){this.select(_35[i],true,true);}}else{var _3a=this.getNode(_35);if(_3a&&!this.isSelected(_3a)){if(!_36){this.clearSelections(true);}if(this.fireEvent("beforeselect",this,_3a,this.selections)!==false){Ext.fly(_3a).addClass(this.selectedClass);this.selections.push(_3a);if(!_37){this.fireEvent("selectionchange",this,this.selections);}}}}},getNode:function(_3b){if(typeof _3b=="string"){return document.getElementById(_3b);}else{if(typeof _3b=="number"){return this.nodes[_3b];}}return _3b;},getNodes:function(_3c,end){var ns=this.nodes;_3c=_3c||0;end=typeof end=="undefined"?ns.length-1:end;var _3f=[];if(_3c<=end){for(var i=_3c;i<=end;i++){_3f.push(ns[i]);}}else{for(var i=_3c;i>=end;i--){_3f.push(ns[i]);}}return _3f;},indexOf:function(_41){_41=this.getNode(_41);if(typeof _41.nodeIndex=="number"){return _41.nodeIndex;}var ns=this.nodes;for(var i=0,len=ns.length;i<len;i++){if(ns[i]==_41){return i;}}return -1;}});Ext.JsonView=function(_45,tpl,_47){Ext.JsonView.superclass.constructor.call(this,_45,tpl,_47);var um=this.el.getUpdateManager();um.setRenderer(this);um.on("update",this.onLoad,this);um.on("failure",this.onLoadException,this);this.events["beforerender"]=true;this.events["load"]=true;this.events["loadexception"]=true;};Ext.extend(Ext.JsonView,Ext.View,{jsonRoot:"",refresh:function(){this.clearSelections();this.el.update("");var _49=[];var o=this.jsonData;if(o&&o.length>0){for(var i=0,len=o.length;i<len;i++){var _4d=this.prepareData(o[i],i,o);_49[_49.length]=this.tpl.apply(_4d);}}else{_49.push(this.emptyText);}this.el.update(_49.join(""));this.nodes=this.el.dom.childNodes;this.updateIndexes(0);},load:function(){var um=this.el.getUpdateManager();um.update.apply(um,arguments);},render:function(el,_50){this.clearSelections();this.el.update("");var o;try{o=Ext.util.JSON.decode(_50.responseText);if(this.jsonRoot){o=eval("o."+this.jsonRoot);}}catch(e){}this.jsonData=o;this.beforeRender();this.refresh();},getCount:function(){return this.jsonData?this.jsonData.length:0;},getNodeData:function(_52){if(_52 instanceof Array){var _53=[];for(var i=0,len=_52.length;i<len;i++){_53.push(this.getNodeData(_52[i]));}return _53;}return this.jsonData[this.indexOf(_52)]||null;},beforeRender:function(){this.snapshot=this.jsonData;if(this.sortInfo){this.sort.apply(this,this.sortInfo);}this.fireEvent("beforerender",this,this.jsonData);},onLoad:function(el,o){this.fireEvent("load",this,this.jsonData,o);},onLoadException:function(el,o){this.fireEvent("loadexception",this,o);},filter:function(_5a,_5b){if(this.jsonData){var _5c=[];var ss=this.snapshot;if(typeof _5b=="string"){var _5e=_5b.length;if(_5e==0){this.clearFilter();return;}_5b=_5b.toLowerCase();for(var i=0,len=ss.length;i<len;i++){var o=ss[i];if(o[_5a].substr(0,_5e).toLowerCase()==_5b){_5c.push(o);}}}else{if(_5b.exec){for(var i=0,len=ss.length;i<len;i++){var o=ss[i];if(_5b.test(o[_5a])){_5c.push(o);}}}else{return;}}this.jsonData=_5c;this.refresh();}},filterBy:function(fn,_63){if(this.jsonData){var _64=[];var ss=this.snapshot;for(var i=0,len=ss.length;i<len;i++){var o=ss[i];if(fn.call(_63||this,o)){_64.push(o);}}this.jsonData=_64;this.refresh();}},clearFilter:function(){if(this.snapshot&&this.jsonData!=this.snapshot){this.jsonData=this.snapshot;this.refresh();}},sort:function(_69,dir,_6b){this.sortInfo=Array.prototype.slice.call(arguments,0);if(this.jsonData){var p=_69;var dsc=dir&&dir.toLowerCase()=="desc";var f=function(o1,o2){var v1=_6b?_6b(o1[p]):o1[p];var v2=_6b?_6b(o2[p]):o2[p];if(v1<v2){return dsc?+1:-1;}else{if(v1>v2){return dsc?-1:+1;}else{return 0;}}};this.jsonData.sort(f);this.refresh();if(this.jsonData!=this.snapshot){this.snapshot.sort(f);}}}});
+
+Ext.JsonView=function(_1,_2,_3){Ext.JsonView.superclass.constructor.call(this,_1,_2,_3);var um=this.el.getUpdateManager();um.setRenderer(this);um.on("update",this.onLoad,this);um.on("failure",this.onLoadException,this);this.events["beforerender"]=true;this.events["load"]=true;this.events["loadexception"]=true;};Ext.extend(Ext.JsonView,Ext.View,{jsonRoot:"",refresh:function(){this.clearSelections();this.el.update("");var _5=[];var o=this.jsonData;if(o&&o.length>0){for(var i=0,_8=o.length;i<_8;i++){var _9=this.prepareData(o[i],i,o);_5[_5.length]=this.tpl.apply(_9);}}else{_5.push(this.emptyText);}this.el.update(_5.join(""));this.nodes=this.el.dom.childNodes;this.updateIndexes(0);},load:function(){var um=this.el.getUpdateManager();um.update.apply(um,arguments);},render:function(el,_c){this.clearSelections();this.el.update("");var o;try{o=Ext.util.JSON.decode(_c.responseText);if(this.jsonRoot){o=eval("o."+this.jsonRoot);}}catch(e){}this.jsonData=o;this.beforeRender();this.refresh();},getCount:function(){return this.jsonData?this.jsonData.length:0;},getNodeData:function(_e){if(_e instanceof Array){var _f=[];for(var i=0,len=_e.length;i<len;i++){_f.push(this.getNodeData(_e[i]));}return _f;}return this.jsonData[this.indexOf(_e)]||null;},beforeRender:function(){this.snapshot=this.jsonData;if(this.sortInfo){this.sort.apply(this,this.sortInfo);}this.fireEvent("beforerender",this,this.jsonData);},onLoad:function(el,o){this.fireEvent("load",this,this.jsonData,o);},onLoadException:function(el,o){this.fireEvent("loadexception",this,o);},filter:function(_16,_17){if(this.jsonData){var _18=[];var ss=this.snapshot;if(typeof _17=="string"){var _1a=_17.length;if(_1a==0){this.clearFilter();return;}_17=_17.toLowerCase();for(var i=0,len=ss.length;i<len;i++){var o=ss[i];if(o[_16].substr(0,_1a).toLowerCase()==_17){_18.push(o);}}}else{if(_17.exec){for(var i=0,len=ss.length;i<len;i++){var o=ss[i];if(_17.test(o[_16])){_18.push(o);}}}else{return;}}this.jsonData=_18;this.refresh();}},filterBy:function(fn,_1f){if(this.jsonData){var _20=[];var ss=this.snapshot;for(var i=0,len=ss.length;i<len;i++){var o=ss[i];if(fn.call(_1f||this,o)){_20.push(o);}}this.jsonData=_20;this.refresh();}},clearFilter:function(){if(this.snapshot&&this.jsonData!=this.snapshot){this.jsonData=this.snapshot;this.refresh();}},sort:function(_25,dir,_27){this.sortInfo=Array.prototype.slice.call(arguments,0);if(this.jsonData){var p=_25;var dsc=dir&&dir.toLowerCase()=="desc";var f=function(o1,o2){var v1=_27?_27(o1[p]):o1[p];var v2=_27?_27(o2[p]):o2[p];if(v1<v2){return dsc?+1:-1;}else{if(v1>v2){return dsc?-1:+1;}else{return 0;}}};this.jsonData.sort(f);this.refresh();if(this.jsonData!=this.snapshot){this.snapshot.sort(f);}}}});
+
+Ext.ColorPalette=function(_1){Ext.ColorPalette.superclass.constructor.call(this,_1);this.addEvents({select:true});if(this.handler){this.on("select",this.handler,this.scope,true);}};Ext.extend(Ext.ColorPalette,Ext.Component,{itemCls:"x-color-palette",value:null,ctype:"Ext.ColorPalette",colors:["000000","993300","333300","003300","003366","000080","333399","333333","800000","FF6600","808000","008000","008080","0000FF","666699","808080","FF0000","FF9900","99CC00","339966","33CCCC","3366FF","800080","969696","FF00FF","FFCC00","FFFF00","00FF00","00FFFF","00CCFF","993366","C0C0C0","FF99CC","FFCC99","FFFF99","CCFFCC","CCFFFF","99CCFF","CC99FF","FFFFFF"],onRender:function(_2){var t=new Ext.MasterTemplate("<tpl><a href=\"#\" class=\"color-{0}\" hidefocus=\"on\"><em><span style=\"background:#{0}\">&#160;</span></em></a></tpl>");var c=this.colors;for(var i=0,_6=c.length;i<_6;i++){t.add([c[i]]);}var el=document.createElement("div");el.className=this.itemCls;t.overwrite(el);_2.dom.appendChild(el);this.el=Ext.get(el);this.el.on("click",this.handleClick,this,{delegate:"a"});},afterRender:function(){if(this.value){var s=this.value;this.value=null;this.select(s);}},handleClick:function(e,t){e.preventDefault();if(!this.disabled){var c=t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];this.select(c.toUpperCase());}},select:function(_c){_c=_c.replace("#","");if(_c!=this.value){var el=this.el;if(this.value){el.child("a.color-"+this.value).removeClass("x-color-palette-sel");}el.child("a.color-"+_c).addClass("x-color-palette-sel");this.value=_c;this.fireEvent("select",this,_c);}}});
+
+Ext.DatePicker=function(_1){Ext.DatePicker.superclass.constructor.call(this,_1);this.value=new Date().clearTime();this.addEvents({select:true});if(this.handler){this.on("select",this.handler,this.scope||this);}if(!this.disabledDatesRE&&this.disabledDates){var dd=this.disabledDates;var re="(?:";for(var i=0;i<dd.length;i++){re+=dd[i];if(i!=dd.length-1){re+="|";}}this.disabledDatesRE=new RegExp(re+")");}};Ext.extend(Ext.DatePicker,Ext.Component,{todayText:"Today",todayTip:"{0} (Spacebar)",minDate:null,maxDate:null,minText:"This date is before the minimum date",maxText:"This date is after the maximum date",format:"m/d/y",disabledDays:null,disabledDaysText:"",disabledDatesRE:null,disabledDatesText:"",constrainToViewport:true,monthNames:Date.monthNames,dayNames:Date.dayNames,nextText:"Next Month (Control+Right)",prevText:"Previous Month (Control+Left)",monthYearText:"Choose a month (Control+Up/Down to move years)",startDay:0,setValue:function(_5){var _6=this.value;this.value=_5.clearTime(true);if(this.el){this.update(this.value);}},getValue:function(){return this.value;},focus:function(){if(this.el){this.update(this.activeDate);}},onRender:function(_7){var m=["<table cellspacing=\"0\">","<tr><td class=\"x-date-left\"><a href=\"#\" title=\"",this.prevText,"\">&#160;</a></td><td class=\"x-date-middle\" align=\"center\"></td><td class=\"x-date-right\"><a href=\"#\" title=\"",this.nextText,"\">&#160;</a></td></tr>","<tr><td colspan=\"3\"><table class=\"x-date-inner\" cellspacing=\"0\"><thead><tr>"];var dn=this.dayNames;for(var i=0;i<7;i++){var d=this.startDay+i;if(d>6){d=d-7;}m.push("<th><span>",dn[d].substr(0,1),"</span></th>");}m[m.length]="</tr></thead><tbody><tr>";for(var i=0;i<42;i++){if(i%7==0&&i!=0){m[m.length]="</tr><tr>";}m[m.length]="<td><a href=\"#\" hidefocus=\"on\" class=\"x-date-date\" tabIndex=\"1\"><em><span></span></em></a></td>";}m[m.length]="</tr></tbody></table></td></tr><tr><td colspan=\"3\" class=\"x-date-bottom\" align=\"center\"></td></tr></table>";var el=document.createElement("div");el.className="x-date-picker";el.innerHTML=m.join("");_7.dom.appendChild(el);this.el=Ext.get(el);new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"),{handler:this.showPrevMonth,scope:this});new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"),{handler:this.showNextMonth,scope:this});this.el.on("mousewheel",this.handleMouseWheel,this);var kn=new Ext.KeyNav(this.el,{"left":function(e){e.ctrlKey?this.showPrevMonth():this.update(this.activeDate.add("d",-1));},"right":function(e){e.ctrlKey?this.showNextMonth():this.update(this.activeDate.add("d",1));},"up":function(e){e.ctrlKey?this.showNextYear():this.update(this.activeDate.add("d",-7));},"down":function(e){e.ctrlKey?this.showPrevYear():this.update(this.activeDate.add("d",7));},"pageUp":function(e){this.showNextMonth();},"pageDown":function(e){this.showPrevMonth();},"enter":function(e){e.stopPropagation();return true;},scope:this});this.el.on("click",this.handleDateClick,this,{delegate:"a.x-date-date"});this.el.addKeyListener(Ext.EventObject.SPACE,this.selectToday,this);this.el.unselectable();this.cells=this.el.select("table.x-date-inner tbody td");this.textNodes=this.el.query("table.x-date-inner tbody span");var _15=new Ext.menu.Menu({plain:true,cls:"x-date-mmenu",allowOtherMenus:true});var _16=Ext.id()+"months";for(var i=0;i<12;i++){_15.add(new Ext.menu.CheckItem({id:"mm-"+i,text:this.monthNames[i],group:_16,month:i}));}_15.on({"beforeshow":function(){_15.items.get("mm-"+(this.activeDate||this.value).getMonth()).setChecked(true);},"itemclick":function(_17){var d=(this.activeDate||this.value).clone();d.setMonth(_17.month);this.update(d);},"show":function(m){this.visibleRegion=m.el.getRegion().adjust(2,2,-2,-2);},"mouseout":function(m,e){if(!this.visibleRegion.contains(e.getPoint())){m.hide();}},scope:this});this.mbtn=new Ext.Button(this.el.child("td.x-date-middle",true),{menu:_15,text:"&#160;",menuAlign:"c-c?",tooltip:this.monthYearText});var _1c=(new Date()).dateFormat(this.format);var _1d=new Ext.Button(this.el.child("td.x-date-bottom",true),{text:String.format(this.todayText,_1c),tooltip:String.format(this.todayTip,_1c),handler:this.selectToday,scope:this});if(Ext.isIE){this.el.repaint();}this.update(this.value);},showPrevMonth:function(e){this.update(this.activeDate.add("mo",-1));},showNextMonth:function(e){this.update(this.activeDate.add("mo",1));},showPrevYear:function(){this.update(this.activeDate.add("y",-1));},showNextYear:function(){this.update(this.activeDate.add("y",1));},handleMouseWheel:function(e){var _21=e.getWheelDelta();if(_21>0){this.showPrevMonth();e.stopEvent();}else{if(_21<0){this.showNextMonth();e.stopEvent();}}},handleDateClick:function(e,t){e.stopEvent();if(t.dateValue&&!Ext.fly(t.parentNode).hasClass("x-date-disabled")){this.setValue(new Date(t.dateValue));this.fireEvent("select",this,this.value);}},selectToday:function(){this.setValue(new Date().clearTime());this.fireEvent("select",this,this.value);},update:function(_24){var vd=this.activeDate;this.activeDate=_24;if(vd&&this.el){var t=_24.getTime();if(vd.getMonth()==_24.getMonth()&&vd.getFullYear()==_24.getFullYear()){this.cells.removeClass("x-date-selected");this.cells.each(function(c){if(c.dom.firstChild.dateValue==t){c.addClass("x-date-selected");setTimeout(function(){try{c.dom.firstChild.focus();}catch(e){}},50);return false;}});return;}}var _28=_24.getDaysInMonth();var _29=_24.getFirstDateOfMonth();var _2a=_29.getDay()-this.startDay;if(_2a<=this.startDay){_2a+=7;}var pm=_24.add("mo",-1);var _2c=pm.getDaysInMonth()-_2a;var _2d=this.cells.elements;var _2e=this.textNodes;_28+=_2a;var day=86400000;var d=(new Date(pm.getFullYear(),pm.getMonth(),_2c)).clearTime();var _31=new Date().clearTime().getTime();var sel=_24.clearTime().getTime();var min=this.minDate?this.minDate.clearTime():Number.NEGATIVE_INFINITY;var max=this.maxDate?this.maxDate.clearTime():Number.POSITIVE_INFINITY;var _35=this.disabledDatesRE;var _36=this.disabledDatesText;var _37=this.disabledDays?this.disabledDays.join(""):false;var _38=this.disabledDaysText;var _39=this.format;var _3a=function(cal,_3c){_3c.title="";var t=d.getTime();_3c.firstChild.dateValue=t;if(t==_31){_3c.className+=" x-date-today";_3c.title=cal.todayText;}if(t==sel){_3c.className+=" x-date-selected";setTimeout(function(){try{_3c.firstChild.focus();}catch(e){}},50);}if(t<min){_3c.className=" x-date-disabled";_3c.title=cal.minText;return;}if(t>max){_3c.className=" x-date-disabled";_3c.title=cal.maxText;return;}if(_37){if(_37.indexOf(d.getDay())!=-1){_3c.title=_38;_3c.className=" x-date-disabled";}}if(_35&&_39){var _3e=d.dateFormat(_39);if(_35.test(_3e)){_3c.title=_36.replace("%0",_3e);_3c.className=" x-date-disabled";}}};var i=0;for(;i<_2a;i++){_2e[i].innerHTML=(++_2c);d.setDate(d.getDate()+1);_2d[i].className="x-date-prevday";_3a(this,_2d[i]);}for(;i<_28;i++){intDay=i-_2a+1;_2e[i].innerHTML=(intDay);d.setDate(d.getDate()+1);_2d[i].className="x-date-active";_3a(this,_2d[i]);}var _40=0;for(;i<42;i++){_2e[i].innerHTML=(++_40);d.setDate(d.getDate()+1);_2d[i].className="x-date-nextday";_3a(this,_2d[i]);}this.mbtn.setText(this.monthNames[_24.getMonth()]+" "+_24.getFullYear());if(!this.internalRender){var _41=this.el.dom.firstChild;var w=_41.offsetWidth;this.el.setWidth(w+this.el.getBorderWidth("lr"));Ext.fly(_41).setWidth(w);this.internalRender=true;if(Ext.isOpera&&!this.secondPass){_41.rows[0].cells[1].style.width=(w-(_41.rows[0].cells[0].offsetWidth+_41.rows[0].cells[2].offsetWidth))+"px";this.secondPass=true;this.update.defer(10,this,[_24]);}}}});
+
+Ext.TabPanel=function(_1,_2){this.el=Ext.get(_1,true);if(_2){if(typeof _2=="boolean"){this.tabPosition=_2?"bottom":"top";}else{Ext.apply(this,_2);}}if(this.tabPosition=="bottom"){this.bodyEl=Ext.get(this.createBody(this.el.dom));this.el.addClass("x-tabs-bottom");}this.stripWrap=Ext.get(this.createStrip(this.el.dom),true);this.stripEl=Ext.get(this.createStripList(this.stripWrap.dom),true);this.stripBody=Ext.get(this.stripWrap.dom.firstChild.firstChild,true);if(Ext.isIE){Ext.fly(this.stripWrap.dom.firstChild).setStyle("overflow-x","hidden");}if(this.tabPosition!="bottom"){this.bodyEl=Ext.get(this.createBody(this.el.dom));this.el.addClass("x-tabs-top");}this.items=[];this.bodyEl.setStyle("position","relative");this.active=null;this.activateDelegate=this.activate.createDelegate(this);this.events={"tabchange":true,"beforetabchange":true};Ext.EventManager.onWindowResize(this.onResize,this);this.cpad=this.el.getPadding("lr");this.hiddenCount=0;Ext.TabPanel.superclass.constructor.call(this);};Ext.extend(Ext.TabPanel,Ext.util.Observable,{tabPosition:"top",currentTabWidth:0,minTabWidth:40,maxTabWidth:250,preferredTabWidth:175,resizeTabs:false,monitorResize:true,addTab:function(id,_4,_5,_6){var _7=new Ext.TabPanelItem(this,id,_4,_6);this.addTabItem(_7);if(_5){_7.setContent(_5);}return _7;},getTab:function(id){return this.items[id];},hideTab:function(id){var t=this.items[id];if(!t.isHidden()){t.setHidden(true);this.hiddenCount++;this.autoSizeTabs();}},unhideTab:function(id){var t=this.items[id];if(t.isHidden()){t.setHidden(false);this.hiddenCount--;this.autoSizeTabs();}},addTabItem:function(_d){this.items[_d.id]=_d;this.items.push(_d);if(this.resizeTabs){_d.setWidth(this.currentTabWidth||this.preferredTabWidth);this.autoSizeTabs();}else{_d.autoSize();}},removeTab:function(id){var _f=this.items;var tab=_f[id];if(!tab){return;}var _11=_f.indexOf(tab);if(this.active==tab&&_f.length>1){var _12=this.getNextAvailable(_11);if(_12){_12.activate();}}this.stripEl.dom.removeChild(tab.pnode.dom);if(tab.bodyEl.dom.parentNode==this.bodyEl.dom){this.bodyEl.dom.removeChild(tab.bodyEl.dom);}_f.splice(_11,1);delete this.items[tab.id];tab.fireEvent("close",tab);tab.purgeListeners();this.autoSizeTabs();},getNextAvailable:function(_13){var _14=this.items;var _15=_13;while(_15<_14.length){var _16=_14[++_15];if(_16&&!_16.isHidden()){return _16;}}_15=_13;while(_15>=0){var _16=_14[--_15];if(_16&&!_16.isHidden()){return _16;}}return null;},disableTab:function(id){var tab=this.items[id];if(tab&&this.active!=tab){tab.disable();}},enableTab:function(id){var tab=this.items[id];tab.enable();},activate:function(id){var tab=this.items[id];if(!tab){return null;}if(tab==this.active){return tab;}var e={};this.fireEvent("beforetabchange",this,e,tab);if(e.cancel!==true&&!tab.disabled){if(this.active){this.active.hide();}this.active=this.items[id];this.active.show();this.fireEvent("tabchange",this,this.active);}return tab;},getActiveTab:function(){return this.active;},syncHeight:function(_1e){var _1f=(_1e||this.el.getHeight())-this.el.getBorderWidth("tb")-this.el.getPadding("tb");var bm=this.bodyEl.getMargins();var _21=_1f-(this.stripWrap.getHeight()||0)-(bm.top+bm.bottom);this.bodyEl.setHeight(_21);return _21;},onResize:function(){if(this.monitorResize){this.autoSizeTabs();}},beginUpdate:function(){this.updating=true;},endUpdate:function(){this.updating=false;this.autoSizeTabs();},autoSizeTabs:function(){var _22=this.items.length;var _23=_22-this.hiddenCount;if(!this.resizeTabs||_22<1||_23<1||this.updating){return;}var w=Math.max(this.el.getWidth()-this.cpad,10);var _25=Math.floor(w/_23);var b=this.stripBody;if(b.getWidth()>w){var _27=this.items;this.setTabWidth(Math.max(_25,this.minTabWidth)-2);if(_25<this.minTabWidth){}}else{if(this.currentTabWidth<this.preferredTabWidth){this.setTabWidth(Math.min(_25,this.preferredTabWidth)-2);}}},getCount:function(){return this.items.length;},setTabWidth:function(_28){this.currentTabWidth=_28;for(var i=0,len=this.items.length;i<len;i++){if(!this.items[i].isHidden()){this.items[i].setWidth(_28);}}},destroy:function(_2b){Ext.EventManager.removeResizeListener(this.onResize,this);for(var i=0,len=this.items.length;i<len;i++){this.items[i].purgeListeners();}if(_2b===true){this.el.update("");this.el.remove();}}});Ext.TabPanelItem=function(_2e,id,_30,_31){this.tabPanel=_2e;this.id=id;this.disabled=false;this.text=_30;this.loaded=false;this.closable=_31;this.bodyEl=Ext.get(_2e.createItemBody(_2e.bodyEl.dom,id));this.bodyEl.setVisibilityMode(Ext.Element.VISIBILITY);this.bodyEl.setStyle("display","block");this.bodyEl.setStyle("zoom","1");this.hideAction();var els=_2e.createStripElements(_2e.stripEl.dom,_30,_31);this.el=Ext.get(els.el,true);this.inner=Ext.get(els.inner,true);this.textEl=Ext.get(this.el.dom.firstChild.firstChild.firstChild,true);this.pnode=Ext.get(els.el.parentNode,true);this.el.on("click",this.onTabClick,this);if(_31){var c=Ext.get(els.close,true);c.dom.title=this.closeText;c.addClassOnOver("close-over");c.on("click",this.closeClick,this);}this.events={"activate":true,"beforeclose":true,"close":true,"deactivate":true};this.hidden=false;Ext.TabPanelItem.superclass.constructor.call(this);};Ext.extend(Ext.TabPanelItem,Ext.util.Observable,{purgeListeners:function(){Ext.util.Observable.prototype.purgeListeners.call(this);this.el.removeAllListeners();},show:function(){this.pnode.addClass("on");this.showAction();if(Ext.isOpera){this.tabPanel.stripWrap.repaint();}this.fireEvent("activate",this.tabPanel,this);},isActive:function(){return this.tabPanel.getActiveTab()==this;},hide:function(){this.pnode.removeClass("on");this.hideAction();this.fireEvent("deactivate",this.tabPanel,this);},hideAction:function(){this.bodyEl.hide();this.bodyEl.setStyle("position","absolute");this.bodyEl.setLeft("-20000px");this.bodyEl.setTop("-20000px");},showAction:function(){this.bodyEl.setStyle("position","relative");this.bodyEl.setTop("");this.bodyEl.setLeft("");this.bodyEl.show();},setTooltip:function(_34){if(Ext.QuickTips&&Ext.QuickTips.isEnabled()){this.textEl.dom.qtip=_34;this.textEl.dom.removeAttribute("title");}else{this.textEl.dom.title=_34;}},onTabClick:function(e){e.preventDefault();this.tabPanel.activate(this.id);},getWidth:function(){return this.inner.getWidth();},setWidth:function(_36){var _37=_36-this.pnode.getPadding("lr");this.inner.setWidth(_37);this.textEl.setWidth(_37-this.inner.getPadding("lr"));this.pnode.setWidth(_36);},setHidden:function(_38){this.hidden=_38;this.pnode.setStyle("display",_38?"none":"");},isHidden:function(){return this.hidden;},getText:function(){return this.text;},autoSize:function(){this.textEl.setWidth(1);this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding("lr"));},setText:function(_39){this.text=_39;this.textEl.update(_39);this.setTooltip(_39);if(!this.tabPanel.resizeTabs){this.autoSize();}},activate:function(){this.tabPanel.activate(this.id);},disable:function(){if(this.tabPanel.active!=this){this.disabled=true;this.pnode.addClass("disabled");}},enable:function(){this.disabled=false;this.pnode.removeClass("disabled");},setContent:function(_3a,_3b){this.bodyEl.update(_3a,_3b);},getUpdateManager:function(){return this.bodyEl.getUpdateManager();},setUrl:function(url,_3d,_3e){if(this.refreshDelegate){this.un("activate",this.refreshDelegate);}this.refreshDelegate=this._handleRefresh.createDelegate(this,[url,_3d,_3e]);this.on("activate",this.refreshDelegate);return this.bodyEl.getUpdateManager();},_handleRefresh:function(url,_40,_41){if(!_41||!this.loaded){var _42=this.bodyEl.getUpdateManager();_42.update(url,_40,this._setLoaded.createDelegate(this));}},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();}},_setLoaded:function(){this.loaded=true;},closeClick:function(e){var o={};e.stopEvent();this.fireEvent("beforeclose",this,o);if(o.cancel!==true){this.tabPanel.removeTab(this.id);}},closeText:"Close this tab"});Ext.TabPanel.prototype.createStrip=function(_45){var _46=document.createElement("div");_46.className="x-tabs-wrap";_45.appendChild(_46);return _46;};Ext.TabPanel.prototype.createStripList=function(_47){_47.innerHTML="<div class=\"x-tabs-strip-wrap\"><table class=\"x-tabs-strip\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody><tr></tr></tbody></table></div>";return _47.firstChild.firstChild.firstChild.firstChild;};Ext.TabPanel.prototype.createBody=function(_48){var _49=document.createElement("div");Ext.id(_49,"tab-body");Ext.fly(_49).addClass("x-tabs-body");_48.appendChild(_49);return _49;};Ext.TabPanel.prototype.createItemBody=function(_4a,id){var _4c=Ext.getDom(id);if(!_4c){_4c=document.createElement("div");_4c.id=id;}Ext.fly(_4c).addClass("x-tabs-item-body");_4a.insertBefore(_4c,_4a.firstChild);return _4c;};Ext.TabPanel.prototype.createStripElements=function(_4d,_4e,_4f){var td=document.createElement("td");_4d.appendChild(td);if(_4f){td.className="x-tabs-closable";if(!this.closeTpl){this.closeTpl=new Ext.Template("<a href=\"#\" class=\"x-tabs-right\"><span class=\"x-tabs-left\"><em class=\"x-tabs-inner\">"+"<span unselectable=\"on\""+(this.disableTooltips?"":" title=\"{text}\"")+" class=\"x-tabs-text\">{text}</span>"+"<div unselectable=\"on\" class=\"close-icon\">&#160;</div></em></span></a>");}var el=this.closeTpl.overwrite(td,{"text":_4e});var _52=el.getElementsByTagName("div")[0];var _53=el.getElementsByTagName("em")[0];return {"el":el,"close":_52,"inner":_53};}else{if(!this.tabTpl){this.tabTpl=new Ext.Template("<a href=\"#\" class=\"x-tabs-right\"><span class=\"x-tabs-left\"><em class=\"x-tabs-inner\">"+"<span unselectable=\"on\""+(this.disableTooltips?"":" title=\"{text}\"")+" class=\"x-tabs-text\">{text}</span></em></span></a>");}var el=this.tabTpl.overwrite(td,{"text":_4e});var _53=el.getElementsByTagName("em")[0];return {"el":el,"inner":_53};}};
+
+Ext.Button=function(_1,_2){Ext.apply(this,_2);this.events={"click":true,"toggle":true,"mouseover":true,"mouseout":true};if(this.menu){this.menu=Ext.menu.MenuMgr.get(this.menu);}if(_1){this.render(_1);}Ext.Button.superclass.constructor.call(this);};Ext.extend(Ext.Button,Ext.util.Observable,{hidden:false,disabled:false,pressed:false,enableToggle:false,menu:undefined,menuAlign:"tl-bl?",menuClassTarget:"tr",tooltipType:"qtip",render:function(_3){var _4;if(this.hideParent){this.parentEl=Ext.get(_3);}if(!this.dhconfig){if(!this.template){if(!Ext.Button.buttonTemplate){Ext.Button.buttonTemplate=new Ext.Template("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"x-btn-wrap\"><tbody><tr>","<td class=\"x-btn-left\"><i>&#160;</i></td><td class=\"x-btn-center\"><em><button class=\"x-btn-text\">{0}</button></em></td><td class=\"x-btn-right\"><i>&#160;</i></td>","</tr></tbody></table>");}this.template=Ext.Button.buttonTemplate;}_4=this.template.append(_3,[this.text||"&#160;"],true);var _5=_4.child("button:first");if(this.cls){_4.addClass(this.cls);}if(this.icon){_5.setStyle("background-image","url("+this.icon+")");}if(this.tooltip){if(typeof this.tooltip=="object"){Ext.QuickTips.tips(Ext.apply({target:_5.id},this.tooltip));}else{_5.dom[this.tooltipType]=this.tooltip;}}}else{_4=Ext.DomHelper.append(Ext.get(_3).dom,this.dhconfig,true);}this.el=_4;if(this.id){this.el.dom.id=this.el.id=this.id;}if(this.menu){this.el.child(this.menuClassTarget).addClass("x-btn-with-menu");this.menu.on("show",this.onMenuShow,this);this.menu.on("hide",this.onMenuHide,this);}_4.addClass("x-btn");if(Ext.isIE&&!Ext.isIE7){this.autoWidth.defer(1,this);}else{this.autoWidth();}_4.on("click",this.onClick,this);_4.on("mouseover",this.onMouseOver,this);_4.on("mouseout",this.onMouseOut,this);_4.on("mousedown",this.onMouseDown,this);if(this.hidden){this.hide();}if(this.disabled){this.disable();}Ext.ButtonToggleMgr.register(this);if(this.pressed){this.el.addClass("x-btn-pressed");}if(this.repeat){var _6=new Ext.util.ClickRepeater(_4,typeof this.repeat=="object"?this.repeat:{});_6.on("click",this.onClick,this);}},getEl:function(){return this.el;},destroy:function(){Ext.ButtonToggleMgr.unregister(this);this.el.removeAllListeners();this.purgeListeners();this.el.remove();},autoWidth:function(){if(this.el){this.el.setWidth("auto");if(Ext.isIE7&&Ext.isStrict){var ib=this.el.child("button");if(ib&&ib.getWidth()>20){ib.clip();ib.setWidth(Ext.util.TextMetrics.measure(ib,this.text).width+ib.getFrameWidth("lr"));}}if(this.minWidth){if(this.hidden){this.el.beginMeasure();}if(this.el.getWidth()<this.minWidth){this.el.setWidth(this.minWidth);}if(this.hidden){this.el.endMeasure();}}}},setHandler:function(_8,_9){this.handler=_8;this.scope=_9;},setText:function(_a){this.text=_a;if(this.el){this.el.child("td.x-btn-center button.x-btn-text").update(_a);}this.autoWidth();},getText:function(){return this.text;},show:function(){this.hidden=false;if(this.el){this[this.hideParent?"parentEl":"el"].setStyle("display","");}},hide:function(){this.hidden=true;if(this.el){this[this.hideParent?"parentEl":"el"].setStyle("display","none");}},setVisible:function(_b){if(_b){this.show();}else{this.hide();}},toggle:function(_c){_c=_c===undefined?!this.pressed:_c;if(_c!=this.pressed){if(_c){this.el.addClass("x-btn-pressed");this.pressed=true;this.fireEvent("toggle",this,true);}else{this.el.removeClass("x-btn-pressed");this.pressed=false;this.fireEvent("toggle",this,false);}if(this.toggleHandler){this.toggleHandler.call(this.scope||this,this,_c);}}},focus:function(){this.el.child("button:first").focus();},disable:function(){if(this.el){this.el.addClass("x-btn-disabled");}this.disabled=true;},enable:function(){if(this.el){this.el.removeClass("x-btn-disabled");}this.disabled=false;},setDisabled:function(v){this[v!==true?"enable":"disable"]();},onClick:function(e){if(e){e.preventDefault();}if(!this.disabled){if(this.enableToggle){this.toggle();}if(this.menu&&!this.menu.isVisible()){this.menu.show(this.el,this.menuAlign);}this.fireEvent("click",this,e);if(this.handler){this.el.removeClass("x-btn-over");this.handler.call(this.scope||this,this,e);}}},onMouseOver:function(e){if(!this.disabled){this.el.addClass("x-btn-over");this.fireEvent("mouseover",this,e);}},onMouseOut:function(e){if(!e.within(this.el,true)){this.el.removeClass("x-btn-over");this.fireEvent("mouseout",this,e);}},onMouseDown:function(){if(!this.disabled){this.el.addClass("x-btn-click");Ext.get(document).on("mouseup",this.onMouseUp,this);}},onMouseUp:function(){this.el.removeClass("x-btn-click");Ext.get(document).un("mouseup",this.onMouseUp,this);},onMenuShow:function(e){this.el.addClass("x-btn-menu-active");},onMenuHide:function(e){this.el.removeClass("x-btn-menu-active");}});Ext.ButtonToggleMgr=function(){var _13={};function toggleGroup(btn,_15){if(_15){var g=_13[btn.toggleGroup];for(var i=0,l=g.length;i<l;i++){if(g[i]!=btn){g[i].toggle(false);}}}}return {register:function(btn){if(!btn.toggleGroup){return;}var g=_13[btn.toggleGroup];if(!g){g=_13[btn.toggleGroup]=[];}g.push(btn);btn.on("toggle",toggleGroup);},unregister:function(btn){if(!btn.toggleGroup){return;}var g=_13[btn.toggleGroup];if(g){g.remove(btn);btn.un("toggle",toggleGroup);}}};}();
+
+Ext.MenuButton=function(_1,_2){Ext.MenuButton.superclass.constructor.call(this,_1,_2);this.events["arrowclick"]=true;};Ext.extend(Ext.MenuButton,Ext.Button,{render:function(_3){var _4=new Ext.Template("<table cellspacing=\"0\" class=\"x-btn-menu-wrap x-btn\"><tr><td>","<table cellspacing=\"0\" class=\"x-btn-wrap x-btn-menu-text-wrap\"><tbody>","<tr><td class=\"x-btn-left\"><i>&#160;</i></td><td class=\"x-btn-center\"><button class=\"x-btn-text\">{0}</button></td></tr>","</tbody></table></td><td>","<table cellspacing=\"0\" class=\"x-btn-wrap x-btn-menu-arrow-wrap\"><tbody>","<tr><td class=\"x-btn-center\"><button class=\"x-btn-menu-arrow-el\">&#160;</button></td><td class=\"x-btn-right\"><i>&#160;</i></td></tr>","</tbody></table></td></tr></table>");var _5=_4.append(_3,[this.text],true);if(this.cls){_5.addClass(this.cls);}if(this.icon){_5.child("button").setStyle("background-image","url("+this.icon+")");}this.el=_5;this.autoWidth();_5.on("click",this.onClick,this);_5.on("mouseover",this.onMouseOver,this);_5.on("mouseout",this.onMouseOut,this);_5.on("mousedown",this.onMouseDown,this);_5.on("mouseup",this.onMouseUp,this);if(this.tooltip){var _6=_5.child("button:first");if(typeof this.tooltip=="object"){Ext.QuickTips.tips(Ext.apply({target:_6.id},this.tooltip));}else{_6.dom[this.tooltipType]=this.tooltip;}}if(this.arrowTooltip){var _6=_5.child("button:nth(2)");_6.dom[this.tooltipType]=this.arrowTooltip;}if(this.hidden){this.hide();}if(this.disabled){this.disable();}if(this.menu){this.menu.on("show",this.onMenuShow,this);this.menu.on("hide",this.onMenuHide,this);}},autoWidth:function(){if(this.el){var _7=this.el.child("table:first");var _8=this.el.child("table:last");this.el.setWidth("auto");_7.setWidth("auto");if(Ext.isIE7&&Ext.isStrict){var ib=this.el.child("button:first");if(ib&&ib.getWidth()>20){ib.clip();ib.setWidth(Ext.util.TextMetrics.measure(ib,this.text).width+ib.getFrameWidth("lr"));}}if(this.minWidth){if(this.hidden){this.el.beginMeasure();}if((_7.getWidth()+_8.getWidth())<this.minWidth){_7.setWidth(this.minWidth-_8.getWidth());}if(this.hidden){this.el.endMeasure();}}this.el.setWidth(_7.getWidth()+_8.getWidth());}},setHandler:function(_a,_b){this.handler=_a;this.scope=_b;},setArrowHandler:function(_c,_d){this.arrowHandler=_c;this.scope=_d;},focus:function(){if(this.el){this.el.child("a:first").focus();}},onClick:function(e){e.preventDefault();if(!this.disabled){if(e.getTarget(".x-btn-menu-arrow-wrap")){if(this.menu&&!this.menu.isVisible()){this.menu.show(this.el,this.menuAlign);}this.fireEvent("arrowclick",this,e);if(this.arrowHandler){this.arrowHandler.call(this.scope||this,this,e);}}else{this.fireEvent("click",this,e);if(this.handler){this.handler.call(this.scope||this,this,e);}}}},onMouseDown:function(e){if(!this.disabled){Ext.fly(e.getTarget("table")).addClass("x-btn-click");}},onMouseUp:function(e){Ext.fly(e.getTarget("table")).removeClass("x-btn-click");}});
+
+Ext.Toolbar=function(_1,_2,_3){Ext.apply(this,_3);this.el=Ext.get(_1);if(this.cls){this.el.addClass(this.cls);}this.el.update("<div class=\"x-toolbar x-small-editor\"><table cellspacing=\"0\"><tr></tr></table></div>");this.tr=this.el.child("tr",true);var _4=0;this.items=new Ext.util.MixedCollection(false,function(o){return o.id||("item"+(++_4));});if(_2){this.add.apply(this,_2);}};Ext.Toolbar.prototype={add:function(){var a=arguments,l=a.length;for(var i=0;i<l;i++){var el=a[i];if(el.applyTo){this.addField(el);}else{if(el.render){this.addItem(el);}else{if(typeof el=="string"){if(el=="separator"||el=="-"){this.addSeparator();}else{if(el==" "){this.addSpacer();}else{this.addText(el);}}}else{if(el.tagName){this.addElement(el);}else{if(typeof el=="object"){this.addButton(el);}}}}}}},getEl:function(){return this.el;},addSeparator:function(){return this.addItem(new Ext.Toolbar.Separator());},addSpacer:function(){return this.addItem(new Ext.Toolbar.Spacer());},addElement:function(el){return this.addItem(new Ext.Toolbar.Item(el));},addItem:function(_b){var td=this.nextBlock();_b.render(td);this.items.add(_b);return _b;},addButton:function(_d){if(_d instanceof Array){var _e=[];for(var i=0,len=_d.length;i<len;i++){_e.push(this.addButton(_d[i]));}return _e;}var b=_d;if(!(_d instanceof Ext.Toolbar.Button)){b=new Ext.Toolbar.Button(_d);}var td=this.nextBlock();b.render(td);this.items.add(b);return b;},addText:function(_13){return this.addItem(new Ext.Toolbar.TextItem(_13));},insertButton:function(_14,_15){if(_15 instanceof Array){var _16=[];for(var i=0,len=_15.length;i<len;i++){_16.push(this.insertButton(_14+i,_15[i]));}return _16;}if(!(_15 instanceof Ext.Toolbar.Button)){_15=new Ext.Toolbar.Button(_15);}var td=document.createElement("td");this.tr.insertBefore(td,this.tr.childNodes[_14]);_15.render(td);this.items.insert(_14,_15);return _15;},addDom:function(_1a,_1b){var td=this.nextBlock();Ext.DomHelper.overwrite(td,_1a);var ti=new Ext.Toolbar.Item(td.firstChild);ti.render(td);this.items.add(ti);return ti;},addField:function(_1e){var td=this.nextBlock();_1e.render(td);var ti=new Ext.Toolbar.Item(td.firstChild);ti.render(td);this.items.add(ti);return ti;},nextBlock:function(){var td=document.createElement("td");this.tr.appendChild(td);return td;}};Ext.Toolbar.Item=function(el){this.el=Ext.getDom(el);this.id=Ext.id(this.el);this.hidden=false;};Ext.Toolbar.Item.prototype={getEl:function(){return this.el;},render:function(td){this.td=td;td.appendChild(this.el);},destroy:function(){this.td.parentNode.removeChild(this.td);},show:function(){this.hidden=false;this.td.style.display="";},hide:function(){this.hidden=true;this.td.style.display="none";},setVisible:function(_24){if(_24){this.show();}else{this.hide();}},focus:function(){Ext.fly(this.el).focus();},disable:function(){Ext.fly(this.td).addClass("x-item-disabled");this.disabled=true;this.el.disabled=true;},enable:function(){Ext.fly(this.td).removeClass("x-item-disabled");this.disabled=false;this.el.disabled=false;}};Ext.Toolbar.Separator=function(){var s=document.createElement("span");s.className="ytb-sep";Ext.Toolbar.Separator.superclass.constructor.call(this,s);};Ext.extend(Ext.Toolbar.Separator,Ext.Toolbar.Item);Ext.Toolbar.Spacer=function(){var s=document.createElement("div");s.className="ytb-spacer";Ext.Toolbar.Separator.superclass.constructor.call(this,s);};Ext.extend(Ext.Toolbar.Spacer,Ext.Toolbar.Item);Ext.Toolbar.TextItem=function(_27){var s=document.createElement("span");s.className="ytb-text";s.innerHTML=_27;Ext.Toolbar.TextItem.superclass.constructor.call(this,s);};Ext.extend(Ext.Toolbar.TextItem,Ext.Toolbar.Item);Ext.Toolbar.Button=function(_29){Ext.Toolbar.Button.superclass.constructor.call(this,null,_29);};Ext.extend(Ext.Toolbar.Button,Ext.Button,{render:function(td){this.td=td;Ext.Toolbar.Button.superclass.render.call(this,td);},destroy:function(){Ext.Toolbar.Button.superclass.destroy.call(this);this.td.parentNode.removeChild(this.td);},show:function(){this.hidden=false;this.td.style.display="";},hide:function(){this.hidden=true;this.td.style.display="none";},disable:function(){Ext.fly(this.td).addClass("x-item-disabled");this.disabled=true;},enable:function(){Ext.fly(this.td).removeClass("x-item-disabled");this.disabled=false;}});Ext.ToolbarButton=Ext.Toolbar.Button;Ext.Toolbar.MenuButton=function(_2b){Ext.Toolbar.MenuButton.superclass.constructor.call(this,null,_2b);};Ext.extend(Ext.Toolbar.MenuButton,Ext.MenuButton,{render:function(td){this.td=td;Ext.Toolbar.MenuButton.superclass.render.call(this,td);},destroy:function(){Ext.Toolbar.MenuButton.superclass.destroy.call(this);this.td.parentNode.removeChild(this.td);},show:function(){this.hidden=false;this.td.style.display="";},hide:function(){this.hidden=true;this.td.style.display="none";}});
+
+Ext.PagingToolbar=function(el,ds,_3){Ext.PagingToolbar.superclass.constructor.call(this,el,null,_3);this.ds=ds;this.cursor=0;this.render(this.el);this.bind(ds);};Ext.extend(Ext.PagingToolbar,Ext.Toolbar,{pageSize:20,displayMsg:"Displaying {0} - {1} of {2}",emptyMsg:"No data to display",beforePageText:"Page",afterPageText:"of {0}",firstText:"First Page",prevText:"Previous Page",nextText:"Next Page",lastText:"Last Page",refreshText:"Refresh",render:function(el){this.first=this.addButton({tooltip:this.firstText,cls:"x-btn-icon x-grid-page-first",disabled:true,handler:this.onClick.createDelegate(this,["first"])});this.prev=this.addButton({tooltip:this.prevText,cls:"x-btn-icon x-grid-page-prev",disabled:true,handler:this.onClick.createDelegate(this,["prev"])});this.addSeparator();this.add(this.beforePageText);this.field=Ext.get(this.addDom({tag:"input",type:"text",size:"3",value:"1",cls:"x-grid-page-number"}).el);this.field.on("keydown",this.onPagingKeydown,this);this.field.on("focus",function(){this.dom.select();});this.afterTextEl=this.addText(String.format(this.afterPageText,1));this.field.setHeight(18);this.addSeparator();this.next=this.addButton({tooltip:this.nextText,cls:"x-btn-icon x-grid-page-next",disabled:true,handler:this.onClick.createDelegate(this,["next"])});this.last=this.addButton({tooltip:this.lastText,cls:"x-btn-icon x-grid-page-last",disabled:true,handler:this.onClick.createDelegate(this,["last"])});this.addSeparator();this.loading=this.addButton({tooltip:this.refreshText,cls:"x-btn-icon x-grid-loading",disabled:true,handler:this.onClick.createDelegate(this,["refresh"])});if(this.displayInfo){this.displayEl=this.el.createChild({cls:"x-paging-info"});}},updateInfo:function(){if(this.displayEl){var _5=this.ds.getCount();var _6=_5==0?this.emptyMsg:String.format(this.displayMsg,this.cursor+1,this.cursor+_5,this.ds.getTotalCount());this.displayEl.update(_6);}},onLoad:function(ds,r,o){this.cursor=o.params?o.params.start:0;var d=this.getPageData(),ap=d.activePage,ps=d.pages;this.afterTextEl.el.innerHTML=String.format(this.afterPageText,d.pages);this.field.dom.value=ap;this.first.setDisabled(ap==1);this.prev.setDisabled(ap==1);this.next.setDisabled(ap==ps);this.last.setDisabled(ap==ps);this.loading.enable();this.updateInfo();},getPageData:function(){var _d=this.ds.getTotalCount();return {total:_d,activePage:Math.ceil((this.cursor+this.pageSize)/this.pageSize),pages:_d<this.pageSize?1:Math.ceil(_d/this.pageSize)};},onLoadError:function(){this.loading.enable();},onPagingKeydown:function(e){var k=e.getKey();var d=this.getPageData();if(k==e.RETURN){var v=this.field.dom.value,_12;if(!v||isNaN(_12=parseInt(v,10))){this.field.dom.value=d.activePage;return;}_12=Math.min(Math.max(1,_12),d.pages)-1;this.ds.load({params:{start:_12*this.pageSize,limit:this.pageSize}});e.stopEvent();}else{if(k==e.HOME||(k==e.UP&&e.ctrlKey)||(k==e.PAGEUP&&e.ctrlKey)||(k==e.RIGHT&&e.ctrlKey)||k==e.END||(k==e.DOWN&&e.ctrlKey)||(k==e.LEFT&&e.ctrlKey)||(k==e.PAGEDOWN&&e.ctrlKey)){var _12=(k==e.HOME||(k==e.DOWN&&e.ctrlKey)||(k==e.LEFT&&e.ctrlKey)||(k==e.PAGEDOWN&&e.ctrlKey))?1:d.pages;this.field.dom.value=_12;this.ds.load({params:{start:(_12-1)*this.pageSize,limit:this.pageSize}});e.stopEvent();}else{if(k==e.UP||k==e.RIGHT||k==e.PAGEUP||k==e.DOWN||k==e.LEFT||k==e.PAGEDOWN){var v=this.field.dom.value,_12;var _13=(e.shiftKey)?10:1;if(k==e.DOWN||k==e.LEFT||k==e.PAGEDOWN){_13*=-1;}if(!v||isNaN(_12=parseInt(v,10))){this.field.dom.value=d.activePage;return;}else{if(parseInt(v,10)+_13>=1&parseInt(v,10)+_13<=d.pages){this.field.dom.value=parseInt(v,10)+_13;_12=Math.min(Math.max(1,_12+_13),d.pages)-1;this.ds.load({params:{start:_12*this.pageSize,limit:this.pageSize}});}}e.stopEvent();}}}},beforeLoad:function(){if(this.loading){this.loading.disable();}},onClick:function(_14){var ds=this.ds;switch(_14){case "first":ds.load({params:{start:0,limit:this.pageSize}});break;case "prev":ds.load({params:{start:Math.max(0,this.cursor-this.pageSize),limit:this.pageSize}});break;case "next":ds.load({params:{start:this.cursor+this.pageSize,limit:this.pageSize}});break;case "last":var _16=ds.getTotalCount();var _17=_16%this.pageSize;var _18=_17?(_16-_17):_16-this.pageSize;ds.load({params:{start:_18,limit:this.pageSize}});break;case "refresh":ds.load({params:{start:this.cursor,limit:this.pageSize}});break;}},unbind:function(ds){ds.un("beforeload",this.beforeLoad,this);ds.un("load",this.onLoad,this);ds.un("loadexception",this.onLoadError,this);},bind:function(ds){ds.on("beforeload",this.beforeLoad,this);ds.on("load",this.onLoad,this);ds.on("loadexception",this.onLoadError,this);}});
+
+Ext.Resizable=function(el,_2){this.el=Ext.get(el);if(_2&&_2.wrap){_2.resizeChild=this.el;this.el=this.el.wrap(typeof _2.wrap=="object"?_2.wrap:{cls:"xresizable-wrap"});this.el.id=this.el.dom.id=_2.resizeChild.id+"-rzwrap";this.el.setStyle("overflow","hidden");this.el.setPositioning(_2.resizeChild.getPositioning());_2.resizeChild.clearPositioning();if(!_2.width||!_2.height){var _3=_2.resizeChild.getSize();this.el.setSize(_3.width,_3.height);}if(_2.pinned&&!_2.adjustments){_2.adjustments="auto";}}this.proxy=this.el.createProxy({tag:"div",cls:"x-resizable-proxy",id:this.el.id+"-rzproxy"});this.proxy.unselectable();this.overlay=this.el.createProxy({tag:"div",cls:"x-resizable-overlay",html:"&#160;"});this.overlay.unselectable();this.overlay.enableDisplayMode("block");this.overlay.on("mousemove",this.onMouseMove,this);this.overlay.on("mouseup",this.onMouseUp,this);Ext.apply(this,_2);if(this.pinned){this.disableTrackOver=true;this.el.addClass("x-resizable-pinned");}var _4=this.el.getStyle("position");if(_4!="absolute"&&_4!="fixed"){this.el.setStyle("position","relative");}if(!this.handles){this.handles="s,e,se";if(this.multiDirectional){this.handles+=",n,w";}}if(this.handles=="all"){this.handles="n s e w ne nw se sw";}var hs=this.handles.split(/\s*?[,;]\s*?| /);var ps=Ext.Resizable.positions;for(var i=0,_8=hs.length;i<_8;i++){if(hs[i]&&ps[hs[i]]){var _9=ps[hs[i]];this[_9]=new Ext.Resizable.Handle(this,_9,this.disableTrackOver,this.transparent);}}this.corner=this.southeast;if(this.handles.indexOf("n")!=-1||this.handles.indexOf("w")!=-1){this.updateBox=true;}this.activeHandle=null;if(this.resizeChild){if(typeof this.resizeChild=="boolean"){this.resizeChild=Ext.get(this.el.dom.firstChild,true);}else{this.resizeChild=Ext.get(this.resizeChild,true);}}if(this.adjustments=="auto"){var rc=this.resizeChild;var hw=this.west,he=this.east,hn=this.north,hs=this.south;if(rc&&(hw||hn)){rc.position("relative");rc.setLeft(hw?hw.el.getWidth():0);rc.setTop(hn?hn.el.getHeight():0);}this.adjustments=[(he?-he.el.getWidth():0)+(hw?-hw.el.getWidth():0),(hn?-hn.el.getHeight():0)+(hs?-hs.el.getHeight():0)-1];}if(this.draggable){this.dd=this.dynamic?this.el.initDD(null):this.el.initDDProxy(null,{dragElId:this.proxy.id});this.dd.setHandleElId(this.resizeChild?this.resizeChild.id:this.el.id);}this.events={"beforeresize":true,"resize":true};if(this.width!==null&&this.height!==null){this.resizeTo(this.width,this.height);}else{this.updateChildSize();}Ext.Resizable.superclass.constructor.call(this);};Ext.extend(Ext.Resizable,Ext.util.Observable,{resizeChild:false,adjustments:[0,0],minWidth:5,minHeight:5,maxWidth:10000,maxHeight:10000,enabled:true,animate:false,duration:0.35,dynamic:false,handles:false,multiDirectional:false,disableTrackOver:false,easing:"easeOutStrong",widthIncrement:0,heightIncrement:0,pinned:false,width:null,height:null,preserveRatio:false,transparent:false,minX:0,minY:0,draggable:false,resizeTo:function(_e,_f){this.el.setSize(_e,_f);this.updateChildSize();this.fireEvent("resize",this,_e,_f,null);},startSizing:function(e){this.fireEvent("beforeresize",this,e);if(this.enabled){this.resizing=true;this.startBox=this.el.getBox();this.startPoint=e.getXY();this.offsets=[(this.startBox.x+this.startBox.width)-this.startPoint[0],(this.startBox.y+this.startBox.height)-this.startPoint[1]];this.proxy.setBox(this.startBox);this.overlay.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.overlay.show();if(!this.dynamic){this.proxy.show();}}},onMouseDown:function(_11,e){if(this.enabled){e.stopEvent();this.activeHandle=_11;this.overlay.setStyle("cursor",_11.el.getStyle("cursor"));this.startSizing(e);}},onMouseUp:function(e){var _14=this.resizeElement();this.resizing=false;this.handleOut();this.overlay.hide();this.fireEvent("resize",this,_14.width,_14.height,e);},updateChildSize:function(){if(this.resizeChild){var el=this.el;var _16=this.resizeChild;var adj=this.adjustments;if(el.dom.offsetWidth){var b=el.getSize(true);_16.setSize(b.width+adj[0],b.height+adj[1]);}if(Ext.isIE){setTimeout(function(){if(el.dom.offsetWidth){var b=el.getSize(true);_16.setSize(b.width+adj[0],b.height+adj[1]);}},10);}}},snap:function(_1a,inc,min){if(!inc||!_1a){return _1a;}var _1d=_1a;var m=_1a%inc;if(m>0){if(m>(inc/2)){_1d=_1a+(inc-m);}else{_1d=_1a-m;}}return Math.max(min,_1d);},resizeElement:function(){var box=this.proxy.getBox();if(this.updateBox){this.el.setBox(box,false,this.animate,this.duration,null,this.easing);}else{this.el.setSize(box.width,box.height,this.animate,this.duration,null,this.easing);}this.updateChildSize();this.proxy.hide();return box;},constrain:function(v,_21,m,mx){if(v-_21<m){_21=v-m;}else{if(v-_21>mx){_21=mx-v;}}return _21;},onMouseMove:function(e){if(this.enabled){try{var _25=this.curSize||this.startBox;var x=this.startBox.x,y=this.startBox.y;var ox=x,oy=y;var w=_25.width,h=_25.height;var ow=w,oh=h;var mw=this.minWidth,mh=this.minHeight;var mxw=this.maxWidth,mxh=this.maxHeight;var wi=this.widthIncrement;var hi=this.heightIncrement;var _34=e.getXY();var _35=-(this.startPoint[0]-Math.max(this.minX,_34[0]));var _36=-(this.startPoint[1]-Math.max(this.minY,_34[1]));var pos=this.activeHandle.position;switch(pos){case "east":w+=_35;w=Math.min(Math.max(mw,w),mxw);break;case "south":h+=_36;h=Math.min(Math.max(mh,h),mxh);break;case "southeast":w+=_35;h+=_36;w=Math.min(Math.max(mw,w),mxw);h=Math.min(Math.max(mh,h),mxh);break;case "north":_36=this.constrain(h,_36,mh,mxh);y+=_36;h-=_36;break;case "west":_35=this.constrain(w,_35,mw,mxw);x+=_35;w-=_35;break;case "northeast":w+=_35;w=Math.min(Math.max(mw,w),mxw);_36=this.constrain(h,_36,mh,mxh);y+=_36;h-=_36;break;case "northwest":_35=this.constrain(w,_35,mw,mxw);_36=this.constrain(h,_36,mh,mxh);y+=_36;h-=_36;x+=_35;w-=_35;break;case "southwest":_35=this.constrain(w,_35,mw,mxw);h+=_36;h=Math.min(Math.max(mh,h),mxh);x+=_35;w-=_35;break;}var sw=this.snap(w,wi,mw);var sh=this.snap(h,hi,mh);if(sw!=w||sh!=h){switch(pos){case "northeast":y-=sh-h;break;case "north":y-=sh-h;break;case "southwest":x-=sw-w;break;case "west":x-=sw-w;break;case "northwest":x-=sw-w;y-=sh-h;break;}w=sw;h=sh;}if(this.preserveRatio){switch(pos){case "southeast":case "east":h=oh*(w/ow);h=Math.min(Math.max(mh,h),mxh);w=ow*(h/oh);break;case "south":w=ow*(h/oh);w=Math.min(Math.max(mw,w),mxw);h=oh*(w/ow);break;case "northeast":w=ow*(h/oh);w=Math.min(Math.max(mw,w),mxw);h=oh*(w/ow);break;case "north":var tw=w;w=ow*(h/oh);w=Math.min(Math.max(mw,w),mxw);h=oh*(w/ow);x+=(tw-w)/2;break;case "southwest":h=oh*(w/ow);h=Math.min(Math.max(mh,h),mxh);var tw=w;w=ow*(h/oh);x+=tw-w;break;case "west":var th=h;h=oh*(w/ow);h=Math.min(Math.max(mh,h),mxh);y+=(th-h)/2;var tw=w;w=ow*(h/oh);x+=tw-w;break;case "northwest":var tw=w;var th=h;h=oh*(w/ow);h=Math.min(Math.max(mh,h),mxh);w=ow*(h/oh);y+=th-h;x+=tw-w;break;}}this.proxy.setBounds(x,y,w,h);if(this.dynamic){this.resizeElement();}}catch(e){}}},handleOver:function(){if(this.enabled){this.el.addClass("x-resizable-over");}},handleOut:function(){if(!this.resizing){this.el.removeClass("x-resizable-over");}},getEl:function(){return this.el;},getResizeChild:function(){return this.resizeChild;},destroy:function(_3c){this.proxy.remove();this.overlay.removeAllListeners();this.overlay.remove();var ps=Ext.Resizable.positions;for(var k in ps){if(typeof ps[k]!="function"&&this[ps[k]]){var h=this[ps[k]];h.el.removeAllListeners();h.el.remove();}}if(_3c){this.el.update("");this.el.remove();}}});Ext.Resizable.positions={n:"north",s:"south",e:"east",w:"west",se:"southeast",sw:"southwest",nw:"northwest",ne:"northeast"};Ext.Resizable.Handle=function(rz,pos,_42,_43){if(!this.tpl){var tpl=Ext.DomHelper.createTemplate({tag:"div",cls:"x-resizable-handle x-resizable-handle-{0}"});tpl.compile();Ext.Resizable.Handle.prototype.tpl=tpl;}this.position=pos;this.rz=rz;this.el=this.tpl.append(rz.el.dom,[this.position],true);this.el.unselectable();if(_43){this.el.setOpacity(0);}this.el.on("mousedown",this.onMouseDown,this);if(!_42){this.el.on("mouseover",this.onMouseOver,this);this.el.on("mouseout",this.onMouseOut,this);}};Ext.Resizable.Handle.prototype={afterResize:function(rz){},onMouseDown:function(e){this.rz.onMouseDown(this,e);},onMouseOver:function(e){this.rz.handleOver(this,e);},onMouseOut:function(e){this.rz.handleOut(this,e);}};
+
+Ext.SplitBar=function(_1,_2,_3,_4,_5){this.el=Ext.get(_1,true);this.el.dom.unselectable="on";this.resizingEl=Ext.get(_2,true);this.orientation=_3||Ext.SplitBar.HORIZONTAL;this.minSize=0;this.maxSize=2000;this.animate=false;this.useShim=false;this.shim=null;if(!_5){this.proxy=Ext.SplitBar.createProxy(this.orientation);}else{this.proxy=Ext.get(_5).dom;}this.dd=new Ext.dd.DDProxy(this.el.dom.id,"XSplitBars",{dragElId:this.proxy.id});this.dd.b4StartDrag=this.onStartProxyDrag.createDelegate(this);this.dd.endDrag=this.onEndProxyDrag.createDelegate(this);this.dragSpecs={};this.adapter=new Ext.SplitBar.BasicLayoutAdapter();this.adapter.init(this);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.placement=_4||(this.el.getX()>this.resizingEl.getX()?Ext.SplitBar.LEFT:Ext.SplitBar.RIGHT);this.el.addClass("x-splitbar-h");}else{this.placement=_4||(this.el.getY()>this.resizingEl.getY()?Ext.SplitBar.TOP:Ext.SplitBar.BOTTOM);this.el.addClass("x-splitbar-v");}this.events={"resize":true,"moved":true,"beforeresize":true};Ext.SplitBar.superclass.constructor.call(this);};Ext.extend(Ext.SplitBar,Ext.util.Observable,{onStartProxyDrag:function(x,y){this.fireEvent("beforeresize",this);if(!this.overlay){var o=Ext.DomHelper.insertFirst(document.body,{cls:"x-drag-overlay",html:"&#160;"},true);o.unselectable();o.enableDisplayMode("block");Ext.SplitBar.prototype.overlay=o;}this.overlay.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.overlay.show();Ext.get(this.proxy).setDisplayed("block");var _9=this.adapter.getElementSize(this);this.activeMinSize=this.getMinimumSize();this.activeMaxSize=this.getMaximumSize();var c1=_9-this.activeMinSize;var c2=Math.max(this.activeMaxSize-_9,0);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.dd.resetConstraints();this.dd.setXConstraint(this.placement==Ext.SplitBar.LEFT?c1:c2,this.placement==Ext.SplitBar.LEFT?c2:c1);this.dd.setYConstraint(0,0);}else{this.dd.resetConstraints();this.dd.setXConstraint(0,0);this.dd.setYConstraint(this.placement==Ext.SplitBar.TOP?c1:c2,this.placement==Ext.SplitBar.TOP?c2:c1);}this.dragSpecs.startSize=_9;this.dragSpecs.startPoint=[x,y];Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd,x,y);},onEndProxyDrag:function(e){Ext.get(this.proxy).setDisplayed(false);var _d=Ext.lib.Event.getXY(e);if(this.overlay){this.overlay.hide();}var _e;if(this.orientation==Ext.SplitBar.HORIZONTAL){_e=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.LEFT?_d[0]-this.dragSpecs.startPoint[0]:this.dragSpecs.startPoint[0]-_d[0]);}else{_e=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.TOP?_d[1]-this.dragSpecs.startPoint[1]:this.dragSpecs.startPoint[1]-_d[1]);}_e=Math.min(Math.max(_e,this.activeMinSize),this.activeMaxSize);if(_e!=this.dragSpecs.startSize){this.adapter.setElementSize(this,_e);this.fireEvent("moved",this,_e);this.fireEvent("resize",this,_e);}},getAdapter:function(){return this.adapter;},setAdapter:function(_f){this.adapter=_f;this.adapter.init(this);},getMinimumSize:function(){return this.minSize;},setMinimumSize:function(_10){this.minSize=_10;},getMaximumSize:function(){return this.maxSize;},setMaximumSize:function(_11){this.maxSize=_11;},setCurrentSize:function(_12){var _13=this.animate;this.animate=false;this.adapter.setElementSize(this,_12);this.animate=_13;},destroy:function(_14){if(this.shim){this.shim.remove();}this.dd.unreg();this.proxy.parentNode.removeChild(this.proxy);if(_14){this.el.remove();}}});Ext.SplitBar.createProxy=function(dir){var _16=new Ext.Element(document.createElement("div"));_16.unselectable();var cls="x-splitbar-proxy";_16.addClass(cls+" "+(dir==Ext.SplitBar.HORIZONTAL?cls+"-h":cls+"-v"));document.body.appendChild(_16.dom);return _16.dom;};Ext.SplitBar.BasicLayoutAdapter=function(){};Ext.SplitBar.BasicLayoutAdapter.prototype={init:function(s){},getElementSize:function(s){if(s.orientation==Ext.SplitBar.HORIZONTAL){return s.resizingEl.getWidth();}else{return s.resizingEl.getHeight();}},setElementSize:function(s,_1b,_1c){if(s.orientation==Ext.SplitBar.HORIZONTAL){if(!s.animate){s.resizingEl.setWidth(_1b);if(_1c){_1c(s,_1b);}}else{s.resizingEl.setWidth(_1b,true,0.1,_1c,"easeOut");}}else{if(!s.animate){s.resizingEl.setHeight(_1b);if(_1c){_1c(s,_1b);}}else{s.resizingEl.setHeight(_1b,true,0.1,_1c,"easeOut");}}}};Ext.SplitBar.AbsoluteLayoutAdapter=function(_1d){this.basic=new Ext.SplitBar.BasicLayoutAdapter();this.container=Ext.get(_1d);};Ext.SplitBar.AbsoluteLayoutAdapter.prototype={init:function(s){this.basic.init(s);},getElementSize:function(s){return this.basic.getElementSize(s);},setElementSize:function(s,_21,_22){this.basic.setElementSize(s,_21,this.moveSplitter.createDelegate(this,[s]));},moveSplitter:function(s){var yes=Ext.SplitBar;switch(s.placement){case yes.LEFT:s.el.setX(s.resizingEl.getRight());break;case yes.RIGHT:s.el.setStyle("right",(this.container.getWidth()-s.resizingEl.getLeft())+"px");break;case yes.TOP:s.el.setY(s.resizingEl.getBottom());break;case yes.BOTTOM:s.el.setY(s.resizingEl.getTop()-s.el.getHeight());break;}}};Ext.SplitBar.VERTICAL=1;Ext.SplitBar.HORIZONTAL=2;Ext.SplitBar.LEFT=1;Ext.SplitBar.RIGHT=2;Ext.SplitBar.TOP=3;Ext.SplitBar.BOTTOM=4;
+
+Ext.Editor=function(_1,_2){Ext.Editor.superclass.constructor.call(this,_2);this.field=_1;this.addEvents({"beforestartedit":true,"startedit":true,"beforecomplete":true,"complete":true,"specialkey":true});};Ext.extend(Ext.Editor,Ext.Component,{value:"",alignment:"c-c?",shadow:"frame",updateEl:false,onRender:function(ct){this.el=new Ext.Layer({shadow:this.shadow,cls:"x-editor",parentEl:ct,shim:this.shim,shadowOffset:3,id:this.id});this.el.setStyle("overflow",Ext.isGecko?"auto":"hidden");this.field.render(this.el);if(Ext.isGecko){this.field.el.dom.setAttribute("autocomplete","off");}this.field.show();this.field.on("blur",this.onBlur,this);this.relayEvents(this.field,["specialkey"]);if(this.field.grow){this.field.on("autosize",this.el.sync,this.el,{delay:1});}},startEdit:function(el,_5){if(this.editing){this.completeEdit();}this.boundEl=Ext.get(el);var v=_5!==undefined?_5:this.boundEl.dom.innerHTML;if(!this.rendered){this.render(this.parentEl||document.body);}if(this.fireEvent("beforestartedit",this,this.boundEl,v)===false){return;}this.startValue=v;this.field.setValue(v);if(this.autoSize){var sz=this.boundEl.getSize();switch(this.autoSize){case "width":this.setSize(sz.width,"");break;case "height":this.setSize("",sz.height);break;default:this.setSize(sz.width,sz.height);}}this.el.alignTo(this.boundEl,this.alignment);this.editing=true;if(Ext.QuickTips){Ext.QuickTips.disable();}this.show();},setSize:function(w,h){this.field.setSize(w,h);if(this.el){this.el.sync();}},realign:function(){this.el.alignTo(this.boundEl,this.alignment);},completeEdit:function(_a){if(!this.editing){return;}var v=this.getValue();if(this.revertInvalid!==false&&!this.field.isValid()){v=this.startValue;this.cancelEdit(true);}if(String(v)==String(this.startValue)&&this.ignoreNoChange){this.editing=false;this.hide();return;}if(this.fireEvent("beforecomplete",this,v,this.startValue)!==false){this.editing=false;if(this.updateEl&&this.boundEl){this.boundEl.update(v);}if(_a!==true){this.hide();}this.fireEvent("complete",this,v,this.startValue);}},onShow:function(){this.el.show();if(this.hideEl!==false){this.boundEl.hide();}this.field.show();this.field.focus();this.fireEvent("startedit",this.boundEl,this.startValue);},cancelEdit:function(_c){if(this.editing){this.setValue(this.startValue);if(_c!==true){this.hide();}}},onBlur:function(){if(this.allowBlur!==true&&this.editing){this.completeEdit();}},onHide:function(){if(this.editing){this.completeEdit();return;}this.field.blur();if(this.field.collapse){this.field.collapse();}this.el.hide();if(this.hideEl!==false){this.boundEl.show();}if(Ext.QuickTips){Ext.QuickTips.enable();}},setValue:function(v){this.field.setValue(v);},getValue:function(){return this.field.getValue();}});
+
+Ext.BasicDialog=function(el,_2){this.el=Ext.get(el);var dh=Ext.DomHelper;if(!this.el&&_2&&_2.autoCreate){if(typeof _2.autoCreate=="object"){if(!_2.autoCreate.id){_2.autoCreate.id=el;}this.el=dh.append(document.body,_2.autoCreate,true);}else{this.el=dh.append(document.body,{tag:"div",id:el,style:"visibility:hidden;"},true);}}el=this.el;el.setDisplayed(true);el.hide=this.hideAction;this.id=el.id;el.addClass("x-dlg");Ext.apply(this,_2);this.proxy=el.createProxy("x-dlg-proxy");this.proxy.hide=this.hideAction;this.proxy.setOpacity(0.5);this.proxy.hide();if(_2.width){el.setWidth(_2.width);}if(_2.height){el.setHeight(_2.height);}this.size=el.getSize();if(typeof _2.x!="undefined"&&typeof _2.y!="undefined"){this.xy=[_2.x,_2.y];}else{this.xy=el.getCenterXY(true);}this.header=el.child("/.x-dlg-hd");this.body=el.child("/.x-dlg-bd");this.footer=el.child("/.x-dlg-ft");if(!this.header){this.header=el.createChild({tag:"div",cls:"x-dlg-hd",html:"&#160;"},this.body?this.body.dom:null);}if(!this.body){this.body=el.createChild({tag:"div",cls:"x-dlg-bd"});}this.header.unselectable();if(this.title){this.header.update(this.title);}this.focusEl=el.createChild({tag:"a",href:"#",cls:"x-dlg-focus",tabIndex:"-1"});this.focusEl.swallowEvent("click",true);this.header.wrap({cls:"x-dlg-hd-right"}).wrap({cls:"x-dlg-hd-left"},true);this.bwrap=this.body.wrap({tag:"div",cls:"x-dlg-dlg-body"});if(this.footer){this.bwrap.dom.appendChild(this.footer.dom);}this.bg=this.el.createChild({tag:"div",cls:"x-dlg-bg",html:"<div class=\"x-dlg-bg-left\"><div class=\"x-dlg-bg-right\"><div class=\"x-dlg-bg-center\">&#160;</div></div></div>"});this.centerBg=this.bg.child("div.x-dlg-bg-center");if(this.autoScroll!==false&&!this.autoTabs){this.body.setStyle("overflow","auto");}this.toolbox=this.el.createChild({cls:"x-dlg-toolbox"});if(this.closable!==false){this.el.addClass("x-dlg-closable");this.close=this.toolbox.createChild({cls:"x-dlg-close"});this.close.on("click",this.closeClick,this);this.close.addClassOnOver("x-dlg-close-over");}if(this.collapsible!==false){this.collapseBtn=this.toolbox.createChild({cls:"x-dlg-collapse"});this.collapseBtn.on("click",this.collapseClick,this);this.collapseBtn.addClassOnOver("x-dlg-collapse-over");this.header.on("dblclick",this.collapseClick,this);}if(this.resizable!==false){this.el.addClass("x-dlg-resizable");this.resizer=new Ext.Resizable(el,{minWidth:this.minWidth||80,minHeight:this.minHeight||80,handles:this.resizeHandles||"all",pinned:true});this.resizer.on("beforeresize",this.beforeResize,this);this.resizer.on("resize",this.onResize,this);}if(this.draggable!==false){el.addClass("x-dlg-draggable");if(!this.proxyDrag){var dd=new Ext.dd.DD(el.dom.id,"WindowDrag");}else{var dd=new Ext.dd.DDProxy(el.dom.id,"WindowDrag",{dragElId:this.proxy.id});}dd.setHandleElId(this.header.id);dd.endDrag=this.endMove.createDelegate(this);dd.startDrag=this.startMove.createDelegate(this);dd.onDrag=this.onDrag.createDelegate(this);dd.scroll=false;this.dd=dd;}if(this.modal){this.mask=dh.append(document.body,{tag:"div",cls:"x-dlg-mask"},true);this.mask.enableDisplayMode("block");this.mask.hide();this.el.addClass("x-dlg-modal");}if(this.shadow){this.shadow=new Ext.Shadow({mode:typeof this.shadow=="string"?this.shadow:"sides",offset:this.shadowOffset});}else{this.shadowOffset=0;}if(Ext.useShims&&this.shim!==false){this.shim=this.el.createShim();this.shim.hide=this.hideAction;this.shim.hide();}else{this.shim=false;}if(this.autoTabs){this.initTabs();}this.events={"keydown":true,"move":true,"resize":true,"beforehide":true,"hide":true,"beforeshow":true,"show":true};el.on("keydown",this.onKeyDown,this);el.on("mousedown",this.toFront,this);Ext.EventManager.onWindowResize(this.adjustViewport,this,true);this.el.hide();Ext.DialogManager.register(this);Ext.BasicDialog.superclass.constructor.call(this);};Ext.extend(Ext.BasicDialog,Ext.util.Observable,{shadowOffset:5,minHeight:80,minWidth:200,minButtonWidth:75,defaultButton:null,buttonAlign:"right",tabTag:"div",firstShow:true,setTitle:function(_5){this.header.update(_5);return this;},closeClick:function(){this.hide();},collapseClick:function(){this[this.collapsed?"expand":"collapse"]();},collapse:function(){if(!this.collapsed){this.collapsed=true;this.el.addClass("x-dlg-collapsed");this.restoreHeight=this.el.getHeight();this.resizeTo(this.el.getWidth(),this.header.getHeight());}},expand:function(){if(this.collapsed){this.collapsed=false;this.el.removeClass("x-dlg-collapsed");this.resizeTo(this.el.getWidth(),this.restoreHeight);}},initTabs:function(){var _6=this.getTabs();while(_6.getTab(0)){_6.removeTab(0);}this.el.select(this.tabTag+".x-dlg-tab").each(function(el){var _8=el.dom;_6.addTab(Ext.id(_8),_8.title);_8.title="";});_6.activate(0);return _6;},beforeResize:function(){this.resizer.minHeight=Math.max(this.minHeight,this.getHeaderFooterHeight(true)+40);},onResize:function(){this.refreshSize();this.syncBodyHeight();this.adjustAssets();this.focus();this.fireEvent("resize",this,this.size.width,this.size.height);},onKeyDown:function(e){if(this.isVisible()){this.fireEvent("keydown",this,e);}},resizeTo:function(_a,_b){this.el.setSize(_a,_b);this.size={width:_a,height:_b};this.syncBodyHeight();if(this.fixedcenter){this.center();}if(this.isVisible()){this.constrainXY();this.adjustAssets();}this.fireEvent("resize",this,_a,_b);return this;},setContentSize:function(w,h){h+=this.getHeaderFooterHeight()+this.body.getMargins("tb");w+=this.body.getMargins("lr")+this.bwrap.getMargins("lr")+this.centerBg.getPadding("lr");h+=this.body.getPadding("tb")+this.bwrap.getBorderWidth("tb")+this.body.getBorderWidth("tb")+this.el.getBorderWidth("tb");w+=this.body.getPadding("lr")+this.bwrap.getBorderWidth("lr")+this.body.getBorderWidth("lr")+this.bwrap.getPadding("lr")+this.el.getBorderWidth("lr");if(this.tabs){h+=this.tabs.stripWrap.getHeight()+this.tabs.bodyEl.getMargins("tb")+this.tabs.bodyEl.getPadding("tb");w+=this.tabs.bodyEl.getMargins("lr")+this.tabs.bodyEl.getPadding("lr");}this.resizeTo(w,h);return this;},addKeyListener:function(_e,fn,_10){var _11,_12,_13,alt;if(typeof _e=="object"&&!(_e instanceof Array)){_11=_e["key"];_12=_e["shift"];_13=_e["ctrl"];alt=_e["alt"];}else{_11=_e;}var _15=function(dlg,e){if((!_12||e.shiftKey)&&(!_13||e.ctrlKey)&&(!alt||e.altKey)){var k=e.getKey();if(_11 instanceof Array){for(var i=0,len=_11.length;i<len;i++){if(_11[i]==k){fn.call(_10||window,dlg,k,e);return;}}}else{if(k==_11){fn.call(_10||window,dlg,k,e);}}}};this.on("keydown",_15);return this;},getTabs:function(){if(!this.tabs){this.el.addClass("x-dlg-auto-tabs");this.body.addClass(this.tabPosition=="bottom"?"x-tabs-bottom":"x-tabs-top");this.tabs=new Ext.TabPanel(this.body.dom,this.tabPosition=="bottom");}return this.tabs;},addButton:function(_1b,_1c,_1d){var dh=Ext.DomHelper;if(!this.footer){this.footer=dh.append(this.bwrap,{tag:"div",cls:"x-dlg-ft"},true);}if(!this.btnContainer){var tb=this.footer.createChild({tag:"div",cls:"x-dlg-btns x-dlg-btns-"+this.buttonAlign,html:"<table cellspacing=\"0\"><tbody><tr></tr></tbody></table><div class=\"x-clear\"></div>"},null,true);this.btnContainer=tb.firstChild.firstChild.firstChild;}var _20={handler:_1c,scope:_1d,minWidth:this.minButtonWidth,hideParent:true};if(typeof _1b=="string"){_20.text=_1b;}else{if(_1b.tag){_20.dhconfig=_1b;}else{Ext.apply(_20,_1b);}}var btn=new Ext.Button(this.btnContainer.appendChild(document.createElement("td")),_20);this.syncBodyHeight();if(!this.buttons){this.buttons=[];}this.buttons.push(btn);return btn;},setDefaultButton:function(btn){this.defaultButton=btn;return this;},getHeaderFooterHeight:function(_23){var _24=0;if(this.header){_24+=this.header.getHeight();}if(this.footer){var fm=this.footer.getMargins();_24+=(this.footer.getHeight()+fm.top+fm.bottom);}_24+=this.bwrap.getPadding("tb")+this.bwrap.getBorderWidth("tb");_24+=this.centerBg.getPadding("tb");return _24;},syncBodyHeight:function(){var bd=this.body,cb=this.centerBg,bw=this.bwrap;var _29=this.size.height-this.getHeaderFooterHeight(false);bd.setHeight(_29-bd.getMargins("tb"));var hh=this.header.getHeight();var h=this.size.height-hh;cb.setHeight(h);bw.setLeftTop(cb.getPadding("l"),hh+cb.getPadding("t"));bw.setHeight(h-cb.getPadding("tb"));bw.setWidth(this.el.getWidth(true)-cb.getPadding("lr"));bd.setWidth(bw.getWidth(true));if(this.tabs){this.tabs.syncHeight();if(Ext.isIE){this.tabs.el.repaint();}}},restoreState:function(){var box=Ext.state.Manager.get(this.stateId||(this.el.id+"-state"));if(box&&box.width){this.xy=[box.x,box.y];this.resizeTo(box.width,box.height);}return this;},beforeShow:function(){this.expand();if(this.fixedcenter){this.xy=this.el.getCenterXY(true);}if(this.modal){Ext.get(document.body).addClass("x-body-masked");this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.mask.show();}this.constrainXY();},animShow:function(){var b=Ext.get(this.animateTarget,true).getBox();this.proxy.setSize(b.width,b.height);this.proxy.setLocation(b.x,b.y);this.proxy.show();this.proxy.setBounds(this.xy[0],this.xy[1],this.size.width,this.size.height,true,0.35,this.showEl.createDelegate(this));},show:function(_2e){if(this.fireEvent("beforeshow",this)===false){return;}if(this.syncHeightBeforeShow){this.syncBodyHeight();}else{if(this.firstShow){this.firstShow=false;this.syncBodyHeight();}}this.animateTarget=_2e||this.animateTarget;if(!this.el.isVisible()){this.beforeShow();if(this.animateTarget){this.animShow();}else{this.showEl();}}return this;},showEl:function(){this.proxy.hide();this.el.setXY(this.xy);this.el.show();this.adjustAssets(true);this.toFront();this.focus();this.fireEvent("show",this);},focus:function(){if(this.defaultButton){this.defaultButton.focus();}else{this.focusEl.focus();}},constrainXY:function(){if(this.constraintoviewport!==false){if(!this.viewSize){if(this.container){var s=this.container.getSize();this.viewSize=[s.width,s.height];}else{this.viewSize=[Ext.lib.Dom.getViewWidth(),Ext.lib.Dom.getViewHeight()];}}var s=Ext.get(this.container||document).getScroll();var x=this.xy[0],y=this.xy[1];var w=this.size.width,h=this.size.height;var vw=this.viewSize[0],vh=this.viewSize[1];var _36=false;if(x+w>vw+s.left){x=vw-w;_36=true;}if(y+h>vh+s.top){y=vh-h;_36=true;}if(x<s.left){x=s.left;_36=true;}if(y<s.top){y=s.top;_36=true;}if(_36){this.xy=[x,y];if(this.isVisible()){this.el.setLocation(x,y);this.adjustAssets();}}}},onDrag:function(){if(!this.proxyDrag){this.xy=this.el.getXY();this.adjustAssets();}},adjustAssets:function(_37){var x=this.xy[0],y=this.xy[1];var w=this.size.width,h=this.size.height;if(_37===true){if(this.shadow){this.shadow.show(this.el);}if(this.shim){this.shim.show();}}if(this.shadow&&this.shadow.isVisible()){this.shadow.show(this.el);}if(this.shim&&this.shim.isVisible()){this.shim.setBounds(x,y,w,h);}},adjustViewport:function(w,h){if(!w||!h){w=Ext.lib.Dom.getViewWidth();h=Ext.lib.Dom.getViewHeight();}this.viewSize=[w,h];if(this.modal&&this.mask.isVisible()){this.mask.setSize(w,h);this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));}if(this.isVisible()){this.constrainXY();}},destroy:function(_3e){if(this.isVisible()){this.animateTarget=null;this.hide();}Ext.EventManager.removeResizeListener(this.adjustViewport,this);if(this.tabs){this.tabs.destroy(_3e);}if(this.shim){this.shim.remove();}if(this.proxy){this.proxy.remove();}if(this.resizer){this.resizer.destroy();}if(this.close){this.close.removeAllListeners();this.close.remove();}if(this.mask){this.mask.remove();}if(this.dd){this.dd.unreg();}if(this.buttons){for(var i=0,len=this.buttons.length;i<len;i++){this.buttons[i].destroy();}}this.el.removeAllListeners();if(_3e===true){this.el.update("");this.el.remove();}Ext.DialogManager.unregister(this);},startMove:function(){if(this.proxyDrag){this.proxy.show();}if(this.constraintoviewport!==false){this.dd.constrainTo(document.body,{right:this.shadowOffset,bottom:this.shadowOffset});}},endMove:function(){if(!this.proxyDrag){Ext.dd.DD.prototype.endDrag.apply(this.dd,arguments);}else{Ext.dd.DDProxy.prototype.endDrag.apply(this.dd,arguments);this.proxy.hide();}this.refreshSize();this.adjustAssets();this.focus();this.fireEvent("move",this,this.xy[0],this.xy[1]);},toFront:function(){Ext.DialogManager.bringToFront(this);return this;},toBack:function(){Ext.DialogManager.sendToBack(this);return this;},center:function(){var xy=this.el.getCenterXY(true);this.moveTo(xy[0],xy[1]);return this;},moveTo:function(x,y){this.xy=[x,y];if(this.isVisible()){this.el.setXY(this.xy);this.adjustAssets();}return this;},alignTo:function(_44,_45,_46){this.xy=this.el.getAlignToXY(_44,_45,_46);if(this.isVisible()){this.el.setXY(this.xy);this.adjustAssets();}return this;},anchorTo:function(el,_48,_49,_4a){var _4b=function(){this.alignTo(el,_48,_49);};Ext.EventManager.onWindowResize(_4b,this);var tm=typeof _4a;if(tm!="undefined"){Ext.EventManager.on(window,"scroll",_4b,this,{buffer:tm=="number"?_4a:50});}_4b.call(this);return this;},isVisible:function(){return this.el.isVisible();},animHide:function(_4d){var b=Ext.get(this.animateTarget).getBox();this.proxy.show();this.proxy.setBounds(this.xy[0],this.xy[1],this.size.width,this.size.height);this.el.hide();this.proxy.setBounds(b.x,b.y,b.width,b.height,true,0.35,this.hideEl.createDelegate(this,[_4d]));},hide:function(_4f){if(this.fireEvent("beforehide",this)===false){return;}if(this.shadow){this.shadow.hide();}if(this.shim){this.shim.hide();}if(this.animateTarget){this.animHide(_4f);}else{this.el.hide();this.hideEl(_4f);}return this;},hideEl:function(_50){this.proxy.hide();if(this.modal){this.mask.hide();Ext.get(document.body).removeClass("x-body-masked");}this.fireEvent("hide",this);if(typeof _50=="function"){_50();}},hideAction:function(){this.setLeft("-10000px");this.setTop("-10000px");this.setStyle("visibility","hidden");},refreshSize:function(){this.size=this.el.getSize();this.xy=this.el.getXY();Ext.state.Manager.set(this.stateId||this.el.id+"-state",this.el.getBox());},setZIndex:function(_51){if(this.modal){this.mask.setStyle("z-index",_51);}if(this.shim){this.shim.setStyle("z-index",++_51);}if(this.shadow){this.shadow.setZIndex(++_51);}this.el.setStyle("z-index",++_51);if(this.proxy){this.proxy.setStyle("z-index",++_51);}if(this.resizer){this.resizer.proxy.setStyle("z-index",++_51);}this.lastZIndex=_51;},getEl:function(){return this.el;}});Ext.DialogManager=function(){var _52={};var _53=[];var _54=null;var _55=function(d1,d2){return (!d1._lastAccess||d1._lastAccess<d2._lastAccess)?-1:1;};var _58=function(){_53.sort(_55);var _59=Ext.DialogManager.zseed;for(var i=0,len=_53.length;i<len;i++){if(_53[i]){_53[i].setZIndex(_59+(i*10));}}};return {zseed:9000,register:function(dlg){_52[dlg.id]=dlg;_53.push(dlg);},unregister:function(dlg){delete _52[dlg.id];if(!_53.indexOf){for(var i=0,len=_53.length;i<len;i++){if(_53[i]==dlg){_53.splice(i,1);return;}}}else{var i=_53.indexOf(dlg);if(i!=-1){_53.splice(i,1);}}},get:function(id){return typeof id=="object"?id:_52[id];},bringToFront:function(dlg){dlg=this.get(dlg);if(dlg!=_54){_54=dlg;dlg._lastAccess=new Date().getTime();_58();}return dlg;},sendToBack:function(dlg){dlg=this.get(dlg);dlg._lastAccess=-(new Date().getTime());_58();return dlg;},hideAll:function(){for(var id in _52){if(_52[id]&&typeof _52[id]!="function"&&_52[id].isVisible()){_52[id].hide();}}}};}();Ext.LayoutDialog=function(el,_65){_65.autoTabs=false;Ext.LayoutDialog.superclass.constructor.call(this,el,_65);this.body.setStyle({overflow:"hidden",position:"relative"});this.layout=new Ext.BorderLayout(this.body.dom,_65);this.layout.monitorWindowResize=false;this.el.addClass("x-dlg-auto-layout");this.center=Ext.BasicDialog.prototype.center;this.on("show",this.layout.layout,this.layout,true);};Ext.extend(Ext.LayoutDialog,Ext.BasicDialog,{endUpdate:function(){this.layout.endUpdate();},beginUpdate:function(){this.layout.beginUpdate();},getLayout:function(){return this.layout;},showEl:function(){Ext.LayoutDialog.superclass.showEl.apply(this,arguments);if(Ext.isIE7){this.layout.layout();}},syncBodyHeight:function(){Ext.LayoutDialog.superclass.syncBodyHeight.call(this);if(this.layout){this.layout.layout();}}});
+
+Ext.MessageBox=function(){var _1,_2,_3,_4;var _5,_6,_7,_8,_9,pp;var _b,_c,_d;var _e=function(_f){_1.hide();Ext.callback(_2.fn,_2.scope||window,[_f,_c.dom.value],1);};var _10=function(){if(_2&&_2.cls){_1.el.removeClass(_2.cls);}if(_4){Ext.TaskMgr.stop(_4);_4=null;}};var _11=function(b){var _13=0;if(!b){_b["ok"].hide();_b["cancel"].hide();_b["yes"].hide();_b["no"].hide();_1.footer.dom.style.display="none";return _13;}_1.footer.dom.style.display="";for(var k in _b){if(typeof _b[k]!="function"){if(b[k]){_b[k].show();_b[k].setText(typeof b[k]=="string"?b[k]:Ext.MessageBox.buttonText[k]);_13+=_b[k].el.getWidth()+15;}else{_b[k].hide();}}}return _13;};var _15=function(d,k,e){if(_2&&_2.closable!==false){_1.hide();}if(e){e.stopEvent();}};return {getDialog:function(){if(!_1){_1=new Ext.BasicDialog("x-msg-box",{autoCreate:true,shadow:true,draggable:true,resizable:false,constraintoviewport:false,fixedcenter:true,collapsible:false,shim:true,modal:true,width:400,height:100,buttonAlign:"center",closeClick:function(){if(_2&&_2.buttons&&_2.buttons.no&&!_2.buttons.cancel){_e("no");}else{_e("cancel");}}});_1.on("hide",_10);_3=_1.mask;_1.addKeyListener(27,_15);_b={};var bt=this.buttonText;_b["ok"]=_1.addButton(bt["ok"],_e.createCallback("ok"));_b["yes"]=_1.addButton(bt["yes"],_e.createCallback("yes"));_b["no"]=_1.addButton(bt["no"],_e.createCallback("no"));_b["cancel"]=_1.addButton(bt["cancel"],_e.createCallback("cancel"));_5=_1.body.createChild({tag:"div",html:"<span class=\"ext-mb-text\"></span><br /><input type=\"text\" class=\"ext-mb-input\"><textarea class=\"ext-mb-textarea\"></textarea><div class=\"ext-mb-progress-wrap\"><div class=\"ext-mb-progress\"><div class=\"ext-mb-progress-bar\">&#160;</div></div></div>"});_6=_5.dom.firstChild;_7=Ext.get(_5.dom.childNodes[2]);_7.enableDisplayMode();_7.addKeyListener([10,13],function(){if(_1.isVisible()&&_2&&_2.buttons){if(_2.buttons.ok){_e("ok");}else{if(_2.buttons.yes){_e("yes");}}}});_8=Ext.get(_5.dom.childNodes[3]);_8.enableDisplayMode();_9=Ext.get(_5.dom.childNodes[4]);_9.enableDisplayMode();var pf=_9.dom.firstChild;pp=Ext.get(pf.firstChild);pp.setHeight(pf.offsetHeight);}return _1;},updateText:function(_1b){if(!_1.isVisible()&&!_2.width){_1.resizeTo(this.maxWidth,100);}_6.innerHTML=_1b||"&#160;";var w=Math.max(Math.min(_2.width||_6.offsetWidth,this.maxWidth),Math.max(_2.minWidth||this.minWidth,_d));if(_2.prompt){_c.setWidth(w);}if(_1.isVisible()){_1.fixedcenter=false;}_1.setContentSize(w,_5.getHeight());if(_1.isVisible()){_1.fixedcenter=true;}return this;},updateProgress:function(_1d,_1e){if(_1e){this.updateText(_1e);}pp.setWidth(Math.floor(_1d*_9.dom.firstChild.offsetWidth));return this;},isVisible:function(){return _1&&_1.isVisible();},hide:function(){if(this.isVisible()){_1.hide();}},show:function(_1f){if(this.isVisible()){this.hide();}var d=this.getDialog();_2=_1f;d.setTitle(_2.title||"&#160;");d.close.setDisplayed(_2.closable!==false);_c=_7;_2.prompt=_2.prompt||(_2.multiline?true:false);if(_2.prompt){if(_2.multiline){_7.hide();_8.show();_8.setHeight(typeof _2.multiline=="number"?_2.multiline:this.defaultTextHeight);_c=_8;}else{_7.show();_8.hide();}}else{_7.hide();_8.hide();}_9.setDisplayed(_2.progress===true);this.updateProgress(0);_c.dom.value=_2.value||"";if(_2.prompt){_1.setDefaultButton(_c);}else{var bs=_2.buttons;var db=null;if(bs&&bs.ok){db=_b["ok"];}else{if(bs&&bs.yes){db=_b["yes"];}}_1.setDefaultButton(db);}_d=_11(_2.buttons);this.updateText(_2.msg);if(_2.cls){d.el.addClass(_2.cls);}d.proxyDrag=_2.proxyDrag===true;d.modal=_2.modal!==false;d.mask=_2.modal!==false?_3:false;if(!d.isVisible()){document.body.appendChild(_1.el.dom);d.animateTarget=null;d.show(_1f.animEl);}return this;},progress:function(_23,msg){this.show({title:_23,msg:msg,buttons:false,progress:true,closable:false,minWidth:this.minProgressWidth});return this;},alert:function(_25,msg,fn,_28){this.show({title:_25,msg:msg,buttons:this.OK,fn:fn,scope:_28});return this;},wait:function(msg,_2a){this.show({title:_2a,msg:msg,buttons:false,closable:false,progress:true,modal:true,width:300,wait:true});_4=Ext.TaskMgr.start({run:function(i){Ext.MessageBox.updateProgress(((((i+20)%20)+1)*5)*0.01);},interval:1000});return this;},confirm:function(_2c,msg,fn,_2f){this.show({title:_2c,msg:msg,buttons:this.YESNO,fn:fn,scope:_2f});return this;},prompt:function(_30,msg,fn,_33,_34){this.show({title:_30,msg:msg,buttons:this.OKCANCEL,fn:fn,minWidth:250,scope:_33,prompt:true,multiline:_34});return this;},OK:{ok:true},YESNO:{yes:true,no:true},OKCANCEL:{ok:true,cancel:true},YESNOCANCEL:{yes:true,no:true,cancel:true},defaultTextHeight:75,maxWidth:600,minWidth:100,minProgressWidth:250,buttonText:{ok:"OK",cancel:"Cancel",yes:"Yes",no:"No"}};}();Ext.Msg=Ext.MessageBox;
+
+Ext.QuickTips=function(){var el,_2,_3,_4,tm,_6,_7,_8={},_9,_a=null,_b,_c;var ce,bd,xy,dd;var _11=false,_12=true,_13=false;var _14=1,_15=1,_16=1,_17=[];var _18=function(e){if(_12){return;}var t=e.getTarget();if(!t||t.nodeType!==1||t==document||t==document.body){return;}if(ce&&t==ce.el){clearTimeout(_15);return;}if(t&&_8[t.id]){_8[t.id].el=t;_14=_1b.defer(tm.showDelay,tm,[_8[t.id]]);return;}var ttp,et=Ext.fly(t);var ns=_6.namespace;if(tm.interceptTitles&&t.title){ttp=t.title;t.qtip=ttp;t.removeAttribute("title");e.preventDefault();}else{ttp=t.qtip||et.getAttributeNS(ns,_6.attribute);}if(ttp){_14=_1b.defer(tm.showDelay,tm,[{el:t,text:ttp,width:et.getAttributeNS(ns,_6.width),autoHide:et.getAttributeNS(ns,_6.hide)!="user",title:et.getAttributeNS(ns,_6.title),cls:et.getAttributeNS(ns,_6.cls)}]);}};var _1f=function(e){clearTimeout(_14);var t=e.getTarget();if(t&&ce&&ce.el==t&&(tm.autoHide&&ce.autoHide!==false)){_15=setTimeout(_22,tm.hideDelay);}};var _23=function(e){if(_12){return;}xy=e.getXY();xy[1]+=18;if(tm.trackMouse&&ce){el.setXY(xy);}};var _25=function(e){clearTimeout(_14);clearTimeout(_15);if(!e.within(el)){if(tm.hideOnClick){_22();tm.disable();}}};var _27=function(e){tm.enable();};var _29=function(){return _b.getPadding("l")+_c.getPadding("r");};var _1b=function(o){if(_12){return;}clearTimeout(_16);ce=o;if(_a){el.removeClass(_a);_a=null;}if(ce.cls){el.addClass(ce.cls);_a=ce.cls;}if(ce.title){_4.update(ce.title);_4.show();}else{_4.update("");_4.hide();}el.dom.style.width=tm.maxWidth+"px";_3.update(o.text);var p=_29(),w=ce.width;if(!w){var td=_3.dom;var aw=Math.max(td.offsetWidth,td.clientWidth,td.scrollWidth);if(aw>tm.maxWidth){w=tm.maxWidth;}else{if(aw<tm.minWidth){w=tm.minWidth;}else{w=aw;}}}el.setWidth(w+p);if(!ce.autoHide){_7.setDisplayed(true);if(dd){dd.unlock();}}else{_7.setDisplayed(false);if(dd){dd.lock();}}if(xy){el.avoidY=xy[1]-18;el.setXY(xy);}if(tm.animate){el.setOpacity(0.1);el.setStyle("visibility","visible");el.fadeIn({callback:_2f});}else{_2f();}};var _2f=function(){if(ce){el.show();_9.enable();if(tm.autoDismiss&&ce.autoHide!==false){_16=setTimeout(_22,tm.autoDismissDelay);}}};var _22=function(_30){clearTimeout(_16);clearTimeout(_15);ce=null;if(el.isVisible()){_9.disable();if(_30!==true&&tm.animate){el.fadeOut({callback:_31});}else{_31();}}};var _31=function(){el.hide();if(_a){el.removeClass(_a);_a=null;}};return {minWidth:40,maxWidth:300,interceptTitles:false,trackMouse:false,hideOnClick:true,showDelay:500,hideDelay:200,autoHide:true,autoDismiss:true,autoDismissDelay:5000,animate:false,init:function(){tm=Ext.QuickTips;_6=tm.tagConfig;if(!_13){el=new Ext.Layer({cls:"x-tip",shadow:"drop",shim:true,constrain:true,shadowOffset:3});el.fxDefaults={stopFx:true};el.update("<div class=\"x-tip-top-left\"><div class=\"x-tip-top-right\"><div class=\"x-tip-top\"></div></div></div><div class=\"x-tip-bd-left\"><div class=\"x-tip-bd-right\"><div class=\"x-tip-bd\"><div class=\"x-tip-close\"></div><h3></h3><div class=\"x-tip-bd-inner\"></div><div class=\"x-clear\"></div></div></div></div><div class=\"x-tip-ft-left\"><div class=\"x-tip-ft-right\"><div class=\"x-tip-ft\"></div></div></div>");_4=el.child("h3");_4.enableDisplayMode("block");_2=el.child("div.x-tip-bd");_3=el.child("div.x-tip-bd-inner");_b=el.child("div.x-tip-bd-left");_c=el.child("div.x-tip-bd-right");_7=el.child("div.x-tip-close");_7.enableDisplayMode("block");_7.on("click",_22);d=Ext.get(document);d.on("mousedown",_25);d.on("mouseup",_27);d.on("mouseover",_18);d.on("mouseout",_1f);d.on("mousemove",_23);_9=d.addKeyListener(27,_22);_9.disable();if(Ext.dd.DD){dd=el.initDD("default",null,{onDrag:function(){el.sync();}});dd.setHandleElId(_4.id);dd.lock();}_13=true;}this.enable();},register:function(_32){var cs=_32 instanceof Array?_32:arguments;for(var i=0,len=cs.length;i<len;i++){var c=cs[i];var _37=c.target;if(_37){if(_37 instanceof Array){for(var j=0,_39=_37.length;j<_39;j++){_8[_37[j]]=c;}}else{_8[typeof _37=="string"?_37:Ext.id(_37.id)]=c;}}}},unregister:function(el){delete _8[Ext.id(el)];},enable:function(){if(_13){_17.pop();if(_17.length<1){_12=false;}}},disable:function(){_12=true;clearTimeout(_14);clearTimeout(_15);clearTimeout(_16);if(ce){_22(true);}_17.push(1);},isEnabled:function(){return !_12;},tagConfig:{namespace:"ext",attribute:"qtip",width:"width",target:"target",title:"qtitle",hide:"hide",cls:"qclass"}};}();Ext.QuickTips.tips=Ext.QuickTips.register;
+
+Ext.tree.TreePanel=function(el,_2){Ext.tree.TreePanel.superclass.constructor.call(this);this.el=Ext.get(el);this.el.addClass("x-tree");this.id=this.el.id;Ext.apply(this,_2);this.addEvents({"beforeload":true,"load":true,"textchange":true,"beforeexpand":true,"beforecollapse":true,"expand":true,"disabledchange":true,"collapse":true,"beforeclick":true,"click":true,"dblclick":true,"contextmenu":true,"beforechildrenrendered":true,"startdrag":true,"enddrag":true,"dragdrop":true,"beforenodedrop":true,"nodedrop":true,"nodedragover":true});if(this.singleExpand){this.on("beforeexpand",this.restrictExpand,this);}};Ext.extend(Ext.tree.TreePanel,Ext.data.Tree,{rootVisible:true,animate:Ext.enableFx,lines:true,enableDD:false,hlDrop:Ext.enableFx,restrictExpand:function(_3){var p=_3.parentNode;if(p){if(p.expandedChild&&p.expandedChild.parentNode==p){p.expandedChild.collapse();}p.expandedChild=_3;}},setRootNode:function(_5){Ext.tree.TreePanel.superclass.setRootNode.call(this,_5);if(!this.rootVisible){_5.ui=new Ext.tree.RootTreeNodeUI(_5);}return _5;},getEl:function(){return this.el;},getLoader:function(){return this.loader;},expandAll:function(){this.root.expand(true);},collapseAll:function(){this.root.collapse(true);},getSelectionModel:function(){if(!this.selModel){this.selModel=new Ext.tree.DefaultSelectionModel();}return this.selModel;},expandPath:function(_6,_7,_8){_7=_7||"id";var _9=_6.split(this.pathSeparator);var _a=this.root;if(_a.attributes[_7]!=_9[1]){if(_8){_8(false,null);}return;}var _b=1;var f=function(){if(++_b==_9.length){if(_8){_8(true,_a);}return;}var c=_a.findChild(_7,_9[_b]);if(!c){if(_8){_8(false,_a);}return;}_a=c;c.expand(false,false,f);};_a.expand(false,false,f);},selectPath:function(_e,_f,_10){_f=_f||"id";var _11=_e.split(this.pathSeparator);var v=_11.pop();if(_11.length>0){var f=function(_14,_15){if(_14&&_15){var n=_15.findChild(_f,v);if(n){n.select();if(_10){_10(true,n);}}}else{if(_10){_10(false,n);}}};this.expandPath(_11.join(this.pathSeparator),_f,f);}else{this.root.select();if(_10){_10(true,this.root);}}},render:function(){this.container=this.el.createChild({tag:"ul",cls:"x-tree-root-ct "+(this.lines?"x-tree-lines":"x-tree-no-lines")});if(this.containerScroll){Ext.dd.ScrollManager.register(this.el);}if((this.enableDD||this.enableDrop)&&!this.dropZone){this.dropZone=new Ext.tree.TreeDropZone(this,this.dropConfig||{ddGroup:this.ddGroup||"TreeDD",appendOnly:this.ddAppendOnly===true});}if((this.enableDD||this.enableDrag)&&!this.dragZone){this.dragZone=new Ext.tree.TreeDragZone(this,this.dragConfig||{ddGroup:this.ddGroup||"TreeDD",scroll:this.ddScroll});}this.getSelectionModel().init(this);this.root.render();if(!this.rootVisible){this.root.renderChildren();}return this;}});
+
+Ext.tree.DefaultSelectionModel=function(){this.selNode=null;this.events={"selectionchange":true,"beforeselect":true};};Ext.extend(Ext.tree.DefaultSelectionModel,Ext.util.Observable,{init:function(_1){this.tree=_1;_1.el.on("keydown",this.onKeyDown,this);_1.on("click",this.onNodeClick,this);},onNodeClick:function(_2,e){this.select(_2);},select:function(_4){var _5=this.selNode;if(_5!=_4&&this.fireEvent("beforeselect",this,_4,_5)!==false){if(_5){_5.ui.onSelectedChange(false);}this.selNode=_4;_4.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,_4,_5);}return _4;},unselect:function(_6){if(this.selNode==_6){this.clearSelections();}},clearSelections:function(){var n=this.selNode;if(n){n.ui.onSelectedChange(false);this.selNode=null;this.fireEvent("selectionchange",this,null);}return n;},getSelectedNode:function(){return this.selNode;},isSelected:function(_8){return this.selNode==_8;},selectPrevious:function(){var s=this.selNode||this.lastSelNode;if(!s){return null;}var ps=s.previousSibling;if(ps){if(!ps.isExpanded()||ps.childNodes.length<1){return this.select(ps);}else{var lc=ps.lastChild;while(lc&&lc.isExpanded()&&lc.childNodes.length>0){lc=lc.lastChild;}return this.select(lc);}}else{if(s.parentNode&&(this.tree.rootVisible||!s.parentNode.isRoot)){return this.select(s.parentNode);}}return null;},selectNext:function(){var s=this.selNode||this.lastSelNode;if(!s){return null;}if(s.firstChild&&s.isExpanded()){return this.select(s.firstChild);}else{if(s.nextSibling){return this.select(s.nextSibling);}else{if(s.parentNode){var _d=null;s.parentNode.bubble(function(){if(this.nextSibling){_d=this.getOwnerTree().selModel.select(this.nextSibling);return false;}});return _d;}}}return null;},onKeyDown:function(e){var s=this.selNode||this.lastSelNode;var sm=this;if(!s){return;}var k=e.getKey();switch(k){case e.DOWN:e.stopEvent();this.selectNext();break;case e.UP:e.stopEvent();this.selectPrevious();break;case e.RIGHT:e.preventDefault();if(s.hasChildNodes()){if(!s.isExpanded()){s.expand();}else{if(s.firstChild){this.select(s.firstChild,e);}}}break;case e.LEFT:e.preventDefault();if(s.hasChildNodes()&&s.isExpanded()){s.collapse();}else{if(s.parentNode&&(this.tree.rootVisible||s.parentNode!=this.tree.getRootNode())){this.select(s.parentNode,e);}}break;}}});Ext.tree.MultiSelectionModel=function(){this.selNodes=[];this.selMap={};this.events={"selectionchange":true};};Ext.extend(Ext.tree.MultiSelectionModel,Ext.util.Observable,{init:function(_12){this.tree=_12;_12.el.on("keydown",this.onKeyDown,this);_12.on("click",this.onNodeClick,this);},onNodeClick:function(_13,e){this.select(_13,e,e.ctrlKey);},select:function(_15,e,_17){if(_17!==true){this.clearSelections(true);}if(this.isSelected(_15)){this.lastSelNode=_15;return _15;}this.selNodes.push(_15);this.selMap[_15.id]=_15;this.lastSelNode=_15;_15.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,this.selNodes);return _15;},unselect:function(_18){if(this.selMap[_18.id]){_18.ui.onSelectedChange(false);var sn=this.selNodes;var _1a=-1;if(sn.indexOf){_1a=sn.indexOf(_18);}else{for(var i=0,len=sn.length;i<len;i++){if(sn[i]==_18){_1a=i;break;}}}if(_1a!=-1){this.selNodes.splice(_1a,1);}delete this.selMap[_18.id];this.fireEvent("selectionchange",this,this.selNodes);}},clearSelections:function(_1d){var sn=this.selNodes;if(sn.length>0){for(var i=0,len=sn.length;i<len;i++){sn[i].ui.onSelectedChange(false);}this.selNodes=[];this.selMap={};if(_1d!==true){this.fireEvent("selectionchange",this,this.selNodes);}}},isSelected:function(_21){return this.selMap[_21.id]?true:false;},getSelectedNodes:function(){return this.selNodes;},onKeyDown:Ext.tree.DefaultSelectionModel.prototype.onKeyDown});
+
+Ext.tree.TreeNode=function(_1){_1=_1||{};if(typeof _1=="string"){_1={text:_1};}this.childrenRendered=false;this.rendered=false;Ext.tree.TreeNode.superclass.constructor.call(this,_1);this.expanded=_1.expanded===true;this.isTarget=_1.isTarget!==false;this.draggable=_1.draggable!==false&&_1.allowDrag!==false;this.allowChildren=_1.allowChildren!==false&&_1.allowDrop!==false;this.text=_1.text;this.disabled=_1.disabled===true;Ext.apply(this.events,{"textchange":true,"beforeexpand":true,"beforecollapse":true,"expand":true,"disabledchange":true,"collapse":true,"beforeclick":true,"click":true,"dblclick":true,"contextmenu":true,"beforechildrenrendered":true});var _2=this.attributes.uiProvider||Ext.tree.TreeNodeUI;this.ui=new _2(this);};Ext.extend(Ext.tree.TreeNode,Ext.data.Node,{preventHScroll:true,isExpanded:function(){return this.expanded;},getUI:function(){return this.ui;},setFirstChild:function(_3){var of=this.firstChild;Ext.tree.TreeNode.superclass.setFirstChild.call(this,_3);if(this.childrenRendered&&of&&_3!=of){of.renderIndent(true,true);}if(this.rendered){this.renderIndent(true,true);}},setLastChild:function(_5){var ol=this.lastChild;Ext.tree.TreeNode.superclass.setLastChild.call(this,_5);if(this.childrenRendered&&ol&&_5!=ol){ol.renderIndent(true,true);}if(this.rendered){this.renderIndent(true,true);}},appendChild:function(){var _7=Ext.tree.TreeNode.superclass.appendChild.apply(this,arguments);if(_7&&this.childrenRendered){_7.render();}this.ui.updateExpandIcon();return _7;},removeChild:function(_8){this.ownerTree.getSelectionModel().unselect(_8);Ext.tree.TreeNode.superclass.removeChild.apply(this,arguments);if(this.childrenRendered){_8.ui.remove();}if(this.childNodes.length<1){this.collapse(false,false);}else{this.ui.updateExpandIcon();}return _8;},insertBefore:function(_9,_a){var _b=Ext.tree.TreeNode.superclass.insertBefore.apply(this,arguments);if(_b&&_a&&this.childrenRendered){_9.render();}this.ui.updateExpandIcon();return _b;},setText:function(_c){var _d=this.text;this.text=_c;this.attributes.text=_c;if(this.rendered){this.ui.onTextChange(this,_c,_d);}this.fireEvent("textchange",this,_c,_d);},select:function(){this.getOwnerTree().getSelectionModel().select(this);},unselect:function(){this.getOwnerTree().getSelectionModel().unselect(this);},isSelected:function(){return this.getOwnerTree().getSelectionModel().isSelected(this);},expand:function(_e,_f,_10){if(!this.expanded){if(this.fireEvent("beforeexpand",this,_e,_f)===false){return;}if(!this.childrenRendered){this.renderChildren();}this.expanded=true;if(!this.isHiddenRoot()&&(this.getOwnerTree().animate&&_f!==false)||_f){this.ui.animExpand(function(){this.fireEvent("expand",this);if(typeof _10=="function"){_10(this);}if(_e===true){this.expandChildNodes(true);}}.createDelegate(this));return;}else{this.ui.expand();this.fireEvent("expand",this);if(typeof _10=="function"){_10(this);}}}else{if(typeof _10=="function"){_10(this);}}if(_e===true){this.expandChildNodes(true);}},isHiddenRoot:function(){return this.isRoot&&!this.getOwnerTree().rootVisible;},collapse:function(_11,_12){if(this.expanded&&!this.isHiddenRoot()){if(this.fireEvent("beforecollapse",this,_11,_12)===false){return;}this.expanded=false;if((this.getOwnerTree().animate&&_12!==false)||_12){this.ui.animCollapse(function(){this.fireEvent("collapse",this);if(_11===true){this.collapseChildNodes(true);}}.createDelegate(this));return;}else{this.ui.collapse();this.fireEvent("collapse",this);}}if(_11===true){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].collapse(true);}}},delayedExpand:function(_16){if(!this.expandProcId){this.expandProcId=this.expand.defer(_16,this);}},cancelExpand:function(){if(this.expandProcId){clearTimeout(this.expandProcId);}this.expandProcId=false;},toggle:function(){if(this.expanded){this.collapse();}else{this.expand();}},ensureVisible:function(_17){var _18=this.getOwnerTree();_18.expandPath(this.getPath(),false,function(){_18.getEl().scrollChildIntoView(this.ui.anchor);Ext.callback(_17);}.createDelegate(this));},expandChildNodes:function(_19){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].expand(_19);}},collapseChildNodes:function(_1d){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].collapse(_1d);}},disable:function(){this.disabled=true;this.unselect();if(this.rendered&&this.ui.onDisableChange){this.ui.onDisableChange(this,true);}this.fireEvent("disabledchange",this,true);},enable:function(){this.disabled=false;if(this.rendered&&this.ui.onDisableChange){this.ui.onDisableChange(this,false);}this.fireEvent("disabledchange",this,false);},renderChildren:function(_21){if(_21!==false){this.fireEvent("beforechildrenrendered",this);}var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].render(true);}this.childrenRendered=true;},sort:function(fn,_26){Ext.tree.TreeNode.superclass.sort.apply(this,arguments);if(this.childrenRendered){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].render(true);}}},render:function(_2a){this.ui.render(_2a);if(!this.rendered){this.rendered=true;if(this.expanded){this.expanded=false;this.expand(false,false);}}},renderIndent:function(_2b,_2c){if(_2c){this.ui.childIndent=null;}this.ui.renderIndent();if(_2b===true&&this.childrenRendered){var cs=this.childNodes;for(var i=0,len=cs.length;i<len;i++){cs[i].renderIndent(true,_2c);}}}});
+
+Ext.tree.AsyncTreeNode=function(_1){this.loaded=false;this.loading=false;Ext.tree.AsyncTreeNode.superclass.constructor.apply(this,arguments);this.events["beforeload"]=true;this.events["load"]=true;};Ext.extend(Ext.tree.AsyncTreeNode,Ext.tree.TreeNode,{expand:function(_2,_3,_4){if(this.loading){var _5;var f=function(){if(!this.loading){clearInterval(_5);this.expand(_2,_3,_4);}}.createDelegate(this);_5=setInterval(f,200);return;}if(!this.loaded){if(this.fireEvent("beforeload",this)===false){return;}this.loading=true;this.ui.beforeLoad(this);var _7=this.loader||this.attributes.loader||this.getOwnerTree().getLoader();if(_7){_7.load(this,this.loadComplete.createDelegate(this,[_2,_3,_4]));return;}}Ext.tree.AsyncTreeNode.superclass.expand.call(this,_2,_3,_4);},isLoading:function(){return this.loading;},loadComplete:function(_8,_9,_a){this.loading=false;this.loaded=true;this.ui.afterLoad(this);this.fireEvent("load",this);this.expand(_8,_9,_a);},isLoaded:function(){return this.loaded;},hasChildNodes:function(){if(!this.isLeaf()&&!this.loaded){return true;}else{return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);}},reload:function(_b){this.collapse(false,false);while(this.firstChild){this.removeChild(this.firstChild);}this.childrenRendered=false;this.loaded=false;if(this.isHiddenRoot()){this.expanded=false;}this.expand(false,false,_b);}});
+
+Ext.tree.TreeNodeUI=function(_1){this.node=_1;this.rendered=false;this.animating=false;this.emptyIcon=Ext.BLANK_IMAGE_URL;};Ext.tree.TreeNodeUI.prototype={removeChild:function(_2){if(this.rendered){this.ctNode.removeChild(_2.ui.getEl());}},beforeLoad:function(){this.addClass("x-tree-node-loading");},afterLoad:function(){this.removeClass("x-tree-node-loading");},onTextChange:function(_3,_4,_5){if(this.rendered){this.textNode.innerHTML=_4;}},onDisableChange:function(_6,_7){this.disabled=_7;if(_7){this.addClass("x-tree-node-disabled");}else{this.removeClass("x-tree-node-disabled");}},onSelectedChange:function(_8){if(_8){this.focus();this.addClass("x-tree-selected");}else{this.removeClass("x-tree-selected");}},onMove:function(_9,_a,_b,_c,_d,_e){this.childIndent=null;if(this.rendered){var _f=_c.ui.getContainer();if(!_f){this.holder=document.createElement("div");this.holder.appendChild(this.wrap);return;}var _10=_e?_e.ui.getEl():null;if(_10){_f.insertBefore(this.wrap,_10);}else{_f.appendChild(this.wrap);}this.node.renderIndent(true);}},addClass:function(cls){if(this.elNode){Ext.fly(this.elNode).addClass(cls);}},removeClass:function(cls){if(this.elNode){Ext.fly(this.elNode).removeClass(cls);}},remove:function(){if(this.rendered){this.holder=document.createElement("div");this.holder.appendChild(this.wrap);}},fireEvent:function(){return this.node.fireEvent.apply(this.node,arguments);},initEvents:function(){this.node.on("move",this.onMove,this);var E=Ext.EventManager;var a=this.anchor;var el=Ext.fly(a);if(Ext.isOpera){el.setStyle("text-decoration","none");}el.on("click",this.onClick,this);el.on("dblclick",this.onDblClick,this);el.on("contextmenu",this.onContextMenu,this);var _16=Ext.fly(this.iconNode);_16.on("click",this.onClick,this);_16.on("dblclick",this.onDblClick,this);_16.on("contextmenu",this.onContextMenu,this);E.on(this.ecNode,"click",this.ecClick,this,true);if(this.node.disabled){this.addClass("x-tree-node-disabled");}if(this.node.hidden){this.addClass("x-tree-node-disabled");}var ot=this.node.getOwnerTree();var dd=ot.enableDD||ot.enableDrag||ot.enableDrop;if(dd&&(!this.node.isRoot||ot.rootVisible)){Ext.dd.Registry.register(this.elNode,{node:this.node,handles:[this.iconNode,this.textNode],isHandle:false});}},hide:function(){if(this.rendered){this.wrap.style.display="none";}},show:function(){if(this.rendered){this.wrap.style.display="";}},onContextMenu:function(e){e.preventDefault();this.focus();this.fireEvent("contextmenu",this.node,e);},onClick:function(e){if(this.dropping){return;}if(this.fireEvent("beforeclick",this.node,e)!==false){if(!this.disabled&&this.node.attributes.href){this.fireEvent("click",this.node,e);return;}e.preventDefault();if(this.disabled){return;}if(this.node.attributes.singleClickExpand&&!this.animating&&this.node.hasChildNodes()){this.node.toggle();}this.fireEvent("click",this.node,e);}else{e.stopEvent();}},onDblClick:function(e){e.preventDefault();if(this.disabled){return;}if(!this.animating&&this.node.hasChildNodes()){this.node.toggle();}this.fireEvent("dblclick",this.node,e);},ecClick:function(e){if(!this.animating&&this.node.hasChildNodes()){this.node.toggle();}},startDrop:function(){this.dropping=true;},endDrop:function(){setTimeout(function(){this.dropping=false;}.createDelegate(this),50);},expand:function(){this.updateExpandIcon();this.ctNode.style.display="";},focus:function(){if(!this.node.preventHScroll){try{this.anchor.focus();}catch(e){}}else{if(!Ext.isIE){try{var _1d=this.node.getOwnerTree().el.dom;var l=_1d.scrollLeft;this.anchor.focus();_1d.scrollLeft=l;}catch(e){}}}},blur:function(){try{this.anchor.blur();}catch(e){}},animExpand:function(_1f){var ct=Ext.get(this.ctNode);ct.stopFx();if(!this.node.hasChildNodes()){this.updateExpandIcon();this.ctNode.style.display="";Ext.callback(_1f);return;}this.animating=true;this.updateExpandIcon();ct.slideIn("t",{callback:function(){this.animating=false;Ext.callback(_1f);},scope:this,duration:this.node.ownerTree.duration||0.25});},highlight:function(){var _21=this.node.getOwnerTree();Ext.fly(this.wrap).highlight(_21.hlColor||"C3DAF9",{endColor:_21.hlBaseColor});},collapse:function(){this.updateExpandIcon();this.ctNode.style.display="none";},animCollapse:function(_22){var ct=Ext.get(this.ctNode);ct.enableDisplayMode("block");ct.stopFx();this.animating=true;this.updateExpandIcon();ct.slideOut("t",{callback:function(){this.animating=false;Ext.callback(_22);},scope:this,duration:this.node.ownerTree.duration||0.25});},getContainer:function(){return this.ctNode;},getEl:function(){return this.wrap;},appendDDGhost:function(_24){_24.appendChild(this.elNode.cloneNode(true));},getDDRepairXY:function(){return Ext.lib.Dom.getXY(this.iconNode);},onRender:function(){this.render();},render:function(_25){var n=this.node;var _27=n.parentNode?n.parentNode.ui.getContainer():n.ownerTree.container.dom;if(!this.rendered){this.rendered=true;var a=n.attributes;this.indentMarkup="";if(n.parentNode){this.indentMarkup=n.parentNode.ui.getChildIndent();}var buf=["<li class=\"x-tree-node\"><div class=\"x-tree-node-el ",n.attributes.cls,"\">","<span class=\"x-tree-node-indent\">",this.indentMarkup,"</span>","<img src=\"",this.emptyIcon,"\" class=\"x-tree-ec-icon\">","<img src=\"",a.icon||this.emptyIcon,"\" class=\"x-tree-node-icon",(a.icon?" x-tree-node-inline-icon":""),(a.iconCls?" "+a.iconCls:""),"\" unselectable=\"on\">","<a hidefocus=\"on\" href=\"",a.href?a.href:"#","\" tabIndex=\"1\" ",a.hrefTarget?" target=\""+a.hrefTarget+"\"":"","><span unselectable=\"on\">",n.text,"</span></a></div>","<ul class=\"x-tree-node-ct\" style=\"display:none;\"></ul>","</li>"];if(_25!==true&&n.nextSibling&&n.nextSibling.ui.getEl()){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",n.nextSibling.ui.getEl(),buf.join(""));}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",_27,buf.join(""));}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1];var cs=this.elNode.childNodes;this.indentNode=cs[0];this.ecNode=cs[1];this.iconNode=cs[2];this.anchor=cs[3];this.textNode=cs[3].firstChild;if(a.qtip){if(this.textNode.setAttributeNS){this.textNode.setAttributeNS("ext","qtip",a.qtip);if(a.qtipTitle){this.textNode.setAttributeNS("ext","qtitle",a.qtipTitle);}}else{this.textNode.setAttribute("ext:qtip",a.qtip);if(a.qtipTitle){this.textNode.setAttribute("ext:qtitle",a.qtipTitle);}}}this.initEvents();if(!this.node.expanded){this.updateExpandIcon();}}else{if(_25===true){_27.appendChild(this.wrap);}}},getAnchor:function(){return this.anchor;},getTextEl:function(){return this.textNode;},getIconEl:function(){return this.iconNode;},updateExpandIcon:function(){if(this.rendered){var n=this.node,c1,c2;var cls=n.isLast()?"x-tree-elbow-end":"x-tree-elbow";var _2f=n.hasChildNodes();if(_2f){if(n.expanded){cls+="-minus";c1="x-tree-node-collapsed";c2="x-tree-node-expanded";}else{cls+="-plus";c1="x-tree-node-expanded";c2="x-tree-node-collapsed";}if(this.wasLeaf){this.removeClass("x-tree-node-leaf");this.wasLeaf=false;}if(this.c1!=c1||this.c2!=c2){Ext.fly(this.elNode).replaceClass(c1,c2);this.c1=c1;this.c2=c2;}}else{if(!this.wasLeaf){Ext.fly(this.elNode).replaceClass("x-tree-node-expanded","x-tree-node-leaf");this.wasLeaf=true;}}var ecc="x-tree-ec-icon "+cls;if(this.ecc!=ecc){this.ecNode.className=ecc;this.ecc=ecc;}}},getChildIndent:function(){if(!this.childIndent){var buf=[];var p=this.node;while(p){if(!p.isRoot||(p.isRoot&&p.ownerTree.rootVisible)){if(!p.isLast()){buf.unshift("<img src=\""+this.emptyIcon+"\" class=\"x-tree-elbow-line\">");}else{buf.unshift("<img src=\""+this.emptyIcon+"\" class=\"x-tree-icon\">");}}p=p.parentNode;}this.childIndent=buf.join("");}return this.childIndent;},renderIndent:function(){if(this.rendered){var _33="";var p=this.node.parentNode;if(p){_33=p.ui.getChildIndent();}if(this.indentMarkup!=_33){this.indentNode.innerHTML=_33;this.indentMarkup=_33;}this.updateExpandIcon();}}};Ext.tree.RootTreeNodeUI=function(){Ext.tree.RootTreeNodeUI.superclass.constructor.apply(this,arguments);};Ext.extend(Ext.tree.RootTreeNodeUI,Ext.tree.TreeNodeUI,{render:function(){if(!this.rendered){var _35=this.node.ownerTree.container.dom;this.node.expanded=true;_35.innerHTML="<div class=\"x-tree-root-node\"></div>";this.wrap=this.ctNode=_35.firstChild;}},collapse:function(){},expand:function(){}});
+
+Ext.tree.TreeLoader=function(_1){this.baseParams={};this.requestMethod="POST";Ext.apply(this,_1);this.events={"beforeload":true,"load":true,"loadexception":true};};Ext.extend(Ext.tree.TreeLoader,Ext.util.Observable,{uiProviders:{},clearOnLoad:true,load:function(_2,_3){if(this.clearOnLoad){while(_2.firstChild){_2.removeChild(_2.firstChild);}}if(_2.attributes.children){var cs=_2.attributes.children;for(var i=0,_6=cs.length;i<_6;i++){_2.appendChild(this.createNode(cs[i]));}if(typeof _3=="function"){_3();}}else{if(this.dataUrl){this.requestData(_2,_3);}}},getParams:function(_7){var _8=[],bp=this.baseParams;for(var _a in bp){if(typeof bp[_a]!="function"){_8.push(encodeURIComponent(_a),"=",encodeURIComponent(bp[_a]),"&");}}_8.push("node=",encodeURIComponent(_7.id));return _8.join("");},requestData:function(_b,_c){if(this.fireEvent("beforeload",this,_b,_c)!==false){var _d=this.getParams(_b);var cb={success:this.handleResponse,failure:this.handleFailure,scope:this,argument:{callback:_c,node:_b}};this.transId=Ext.lib.Ajax.request(this.requestMethod,this.dataUrl,cb,_d);}else{if(typeof _c=="function"){_c();}}},isLoading:function(){return this.transId?true:false;},abort:function(){if(this.isLoading()){Ext.lib.Ajax.abort(this.transId);}},createNode:function(_f){if(this.applyLoader!==false){_f.loader=this;}if(typeof _f.uiProvider=="string"){_f.uiProvider=this.uiProviders[_f.uiProvider]||eval(_f.uiProvider);}return (_f.leaf?new Ext.tree.TreeNode(_f):new Ext.tree.AsyncTreeNode(_f));},processResponse:function(_10,_11,_12){var _13=_10.responseText;try{var o=eval("("+_13+")");for(var i=0,len=o.length;i<len;i++){var n=this.createNode(o[i]);if(n){_11.appendChild(n);}}if(typeof _12=="function"){_12(this,_11);}}catch(e){this.handleFailure(_10);}},handleResponse:function(_18){this.transId=false;var a=_18.argument;this.processResponse(_18,a.node,a.callback);this.fireEvent("load",this,a.node,_18);},handleFailure:function(_1a){this.transId=false;var a=_1a.argument;this.fireEvent("loadexception",this,a.node,_1a);if(typeof a.callback=="function"){a.callback(this,a.node);}}});
+
+Ext.tree.TreeFilter=function(_1,_2){this.tree=_1;this.filtered={};Ext.apply(this,_2,{clearBlank:false,reverse:false,autoClear:false,remove:false});};Ext.tree.TreeFilter.prototype={filter:function(_3,_4,_5){_4=_4||"text";var f;if(typeof _3=="string"){var _7=_3.length;if(_7==0&&this.clearBlank){this.clearFilter();return;}_3=_3.toLowerCase();f=function(n){return n.attributes[_4].substr(0,_7).toLowerCase()==_3;};}else{if(_3.exec){f=function(n){return _3.test(n.attributes[_4]);};}else{throw "Illegal filter type, must be string or regex";}}this.filterBy(f,null,_5);},filterBy:function(fn,_b,_c){_c=_c||this.tree.root;if(this.autoClear){this.clearFilter();}var af=this.filtered,rv=this.reverse;var f=function(n){if(n==_c){return true;}if(af[n.id]){return false;}var m=fn.call(_b||n,n);if(!m||rv){af[n.id]=n;n.ui.hide();return false;}return true;};_c.cascade(f);if(this.remove){for(var id in af){if(typeof id!="function"){var n=af[id];if(n&&n.parentNode){n.parentNode.removeChild(n);}}}}},clear:function(){var t=this.tree;var af=this.filtered;for(var id in af){if(typeof id!="function"){var n=af[id];if(n){n.ui.show();}}}this.filtered={};}};
+
+Ext.tree.TreeSorter=function(_1,_2){Ext.apply(this,_2);_1.on("beforechildrenrendered",this.doSort,this);_1.on("append",this.updateSort,this);_1.on("insert",this.updateSort,this);var _3=this.dir&&this.dir.toLowerCase()=="desc";var p=this.property||"text";var _5=this.sortType;var fs=this.folderSort;var cs=this.caseSensitive===true;var _8=this.leafAttr||"leaf";this.sortFn=function(n1,n2){if(fs){if(n1.attributes[_8]&&!n2.attributes[_8]){return 1;}if(!n1.attributes[_8]&&n2.attributes[_8]){return -1;}}var v1=_5?_5(n1):(cs?n1[p]:n1[p].toUpperCase());var v2=_5?_5(n2):(cs?n2[p]:n2[p].toUpperCase());if(v1<v2){return _3?+1:-1;}else{if(v1>v2){return _3?-1:+1;}else{return 0;}}};};Ext.tree.TreeSorter.prototype={doSort:function(_d){_d.sort(this.sortFn);},compareNodes:function(n1,n2){return (n1.text.toUpperCase()>n2.text.toUpperCase()?1:-1);},updateSort:function(_10,_11){if(_11.childrenRendered){this.doSort.defer(1,this,[_11]);}}};
+
+if(Ext.dd.DropZone){Ext.tree.TreeDropZone=function(_1,_2){this.allowParentInsert=false;this.allowContainerDrop=false;this.appendOnly=false;Ext.tree.TreeDropZone.superclass.constructor.call(this,_1.container,_2);this.tree=_1;this.lastInsertClass="x-tree-no-status";this.dragOverData={};};Ext.extend(Ext.tree.TreeDropZone,Ext.dd.DropZone,{ddGroup:"TreeDD",expandDelay:1000,expandNode:function(_3){if(_3.hasChildNodes()&&!_3.isExpanded()){_3.expand(false,null,this.triggerCacheRefresh.createDelegate(this));}},queueExpand:function(_4){this.expandProcId=this.expandNode.defer(this.expandDelay,this,[_4]);},cancelExpand:function(){if(this.expandProcId){clearTimeout(this.expandProcId);this.expandProcId=false;}},isValidDropPoint:function(n,pt,dd,e,_9){if(!n||!_9){return false;}var _a=n.node;var _b=_9.node;if(!(_a&&_a.isTarget&&pt)){return false;}if(pt=="append"&&_a.allowChildren===false){return false;}if((pt=="above"||pt=="below")&&(_a.parentNode&&_a.parentNode.allowChildren===false)){return false;}if(_b&&(_a==_b||_b.contains(_a))){return false;}var _c=this.dragOverData;_c.tree=this.tree;_c.target=_a;_c.data=_9;_c.point=pt;_c.source=dd;_c.rawEvent=e;_c.dropNode=_b;_c.cancel=false;var _d=this.tree.fireEvent("nodedragover",_c);return _c.cancel===false&&_d!==false;},getDropPoint:function(e,n,dd){var tn=n.node;if(tn.isRoot){return tn.allowChildren!==false?"append":false;}var _12=n.ddel;var t=Ext.lib.Dom.getY(_12),b=t+_12.offsetHeight;var y=Ext.lib.Event.getPageY(e);var _16=tn.allowChildren===false||tn.isLeaf();if(this.appendOnly||tn.parentNode.allowChildren===false){return _16?false:"append";}var _17=false;if(!this.allowParentInsert){_17=tn.hasChildNodes()&&tn.isExpanded();}var q=(b-t)/(_16?2:3);if(y>=t&&y<(t+q)){return "above";}else{if(!_17&&(_16||y>=b-q&&y<=b)){return "below";}else{return "append";}}},onNodeEnter:function(n,dd,e,_1c){this.cancelExpand();},onNodeOver:function(n,dd,e,_20){var pt=this.getDropPoint(e,n,dd);var _22=n.node;if(!this.expandProcId&&pt=="append"&&_22.hasChildNodes()&&!n.node.isExpanded()){this.queueExpand(_22);}else{if(pt!="append"){this.cancelExpand();}}var _23=this.dropNotAllowed;if(this.isValidDropPoint(n,pt,dd,e,_20)){if(pt){var el=n.ddel;var cls;if(pt=="above"){_23=n.node.isFirst()?"x-tree-drop-ok-above":"x-tree-drop-ok-between";cls="x-tree-drag-insert-above";}else{if(pt=="below"){_23=n.node.isLast()?"x-tree-drop-ok-below":"x-tree-drop-ok-between";cls="x-tree-drag-insert-below";}else{_23="x-tree-drop-ok-append";cls="x-tree-drag-append";}}if(this.lastInsertClass!=cls){Ext.fly(el).replaceClass(this.lastInsertClass,cls);this.lastInsertClass=cls;}}}return _23;},onNodeOut:function(n,dd,e,_29){this.cancelExpand();this.removeDropIndicators(n);},onNodeDrop:function(n,dd,e,_2d){var _2e=this.getDropPoint(e,n,dd);var _2f=n.node;_2f.ui.startDrop();if(!this.isValidDropPoint(n,_2e,dd,e,_2d)){_2f.ui.endDrop();return false;}var _30=_2d.node||(dd.getTreeNode?dd.getTreeNode(_2d,_2f,_2e,e):null);var _31={tree:this.tree,target:_2f,data:_2d,point:_2e,source:dd,rawEvent:e,dropNode:_30,cancel:!_30};var _32=this.tree.fireEvent("beforenodedrop",_31);if(_32===false||_31.cancel===true||!_31.dropNode){_2f.ui.endDrop();return false;}_2f=_31.target;if(_2e=="append"&&!_2f.isExpanded()){_2f.expand(false,null,function(){this.completeDrop(_31);}.createDelegate(this));}else{this.completeDrop(_31);}return true;},completeDrop:function(de){var ns=de.dropNode,p=de.point,t=de.target;if(!(ns instanceof Array)){ns=[ns];}var n;for(var i=0,len=ns.length;i<len;i++){n=ns[i];if(p=="above"){t.parentNode.insertBefore(n,t);}else{if(p=="below"){t.parentNode.insertBefore(n,t.nextSibling);}else{t.appendChild(n);}}}n.ui.focus();if(this.tree.hlDrop){n.ui.highlight();}t.ui.endDrop();this.tree.fireEvent("nodedrop",de);},afterNodeMoved:function(dd,_3b,e,_3d,_3e){if(this.tree.hlDrop){_3e.ui.focus();_3e.ui.highlight();}this.tree.fireEvent("nodedrop",this.tree,_3d,_3b,dd,e);},getTree:function(){return this.tree;},removeDropIndicators:function(n){if(n&&n.ddel){var el=n.ddel;Ext.fly(el).removeClass(["x-tree-drag-insert-above","x-tree-drag-insert-below","x-tree-drag-append"]);this.lastInsertClass="_noclass";}},beforeDragDrop:function(_41,e,id){this.cancelExpand();return true;},afterRepair:function(_44){if(_44&&Ext.enableFx){_44.node.ui.highlight();}this.hideProxy();}});}
+
+if(Ext.dd.DragZone){Ext.tree.TreeDragZone=function(_1,_2){Ext.tree.TreeDragZone.superclass.constructor.call(this,_1.getEl(),_2);this.tree=_1;};Ext.extend(Ext.tree.TreeDragZone,Ext.dd.DragZone,{ddGroup:"TreeDD",onBeforeDrag:function(_3,e){var n=_3.node;return n&&n.draggable&&!n.disabled;},onInitDrag:function(e){var _7=this.dragData;this.tree.getSelectionModel().select(_7.node);this.proxy.update("");_7.node.ui.appendDDGhost(this.proxy.ghost.dom);this.tree.fireEvent("startdrag",this.tree,_7.node,e);},getRepairXY:function(e,_9){return _9.node.ui.getDDRepairXY();},onEndDrag:function(_a,e){this.tree.fireEvent("enddrag",this.tree,_a.node,e);},onValidDrop:function(dd,e,id){this.tree.fireEvent("dragdrop",this.tree,this.dragData.node,dd,e);this.hideProxy();},beforeInvalidDrop:function(e,id){var sm=this.tree.getSelectionModel();sm.clearSelections();sm.select(this.dragData.node);}});}
+
+Ext.tree.TreeEditor=function(_1,_2){_2=_2||{};var _3=_2.events?_2:new Ext.form.TextField(_2);Ext.tree.TreeEditor.superclass.constructor.call(this,_3);this.tree=_1;_1.on("beforeclick",this.beforeNodeClick,this);_1.el.on("mousedown",this.hide,this);this.on("complete",this.updateNode,this);this.on("beforestartedit",this.fitToTree,this);this.on("startedit",this.bindScroll,this,{delay:10});this.on("specialkey",this.onSpecialKey,this);};Ext.extend(Ext.tree.TreeEditor,Ext.Editor,{alignment:"l-l",autoSize:false,hideEl:false,cls:"x-small-editor x-tree-editor",shim:false,shadow:"frame",maxWidth:250,fitToTree:function(ed,el){var td=this.tree.el.dom,nd=el.dom;if(td.scrollLeft>nd.offsetLeft){td.scrollLeft=nd.offsetLeft;}var w=Math.min(this.maxWidth,td.clientWidth-Math.max(0,nd.offsetLeft-td.scrollLeft)-5);this.setSize(w,"");},triggerEdit:function(_9){this.completeEdit();this.editNode=_9;this.startEdit(_9.ui.textNode,_9.text);},bindScroll:function(){this.tree.el.on("scroll",this.cancelEdit,this);},beforeNodeClick:function(_a){if(this.tree.getSelectionModel().isSelected(_a)){this.triggerEdit(_a);return false;}},updateNode:function(ed,_c){this.tree.el.un("scroll",this.cancelEdit,this);this.editNode.setText(_c);},onSpecialKey:function(_d,e){var k=e.getKey();if(k==e.ESC){this.cancelEdit();e.stopEvent();}else{if(k==e.ENTER&&!e.hasModifier()){this.completeEdit();e.stopEvent();}}}});
+
+Ext.menu.Menu=function(_1){Ext.apply(this,_1);this.id=this.id||Ext.id();this.events={beforeshow:true,beforehide:true,show:true,hide:true,click:true,mouseover:true,mouseout:true,itemclick:true};Ext.menu.MenuMgr.register(this);var _2=this.items;this.items=new Ext.util.MixedCollection();if(_2){this.add.apply(this,_2);}};Ext.extend(Ext.menu.Menu,Ext.util.Observable,{minWidth:120,shadow:"sides",subMenuAlign:"tl-tr?",defaultAlign:"tl-bl?",allowOtherMenus:false,render:function(){if(this.el){return;}var el=this.el=new Ext.Layer({cls:"x-menu",shadow:this.shadow,constrain:false,parentEl:this.parentEl||document.body,zindex:15000});this.keyNav=new Ext.menu.MenuNav(this);if(this.plain){el.addClass("x-menu-plain");}if(this.cls){el.addClass(this.cls);}this.focusEl=el.createChild({tag:"a",cls:"x-menu-focus",href:"#",onclick:"return false;",tabIndex:"-1"});var ul=el.createChild({tag:"ul",cls:"x-menu-list"});ul.on("click",this.onClick,this);ul.on("mouseover",this.onMouseOver,this);ul.on("mouseout",this.onMouseOut,this);this.items.each(function(_5){var li=document.createElement("li");li.className="x-menu-list-item";ul.dom.appendChild(li);_5.render(li,this);},this);this.ul=ul;this.autoWidth();},autoWidth:function(){var el=this.el,ul=this.ul;if(!el){return;}var w=this.width;if(w){el.setWidth(w);}else{if(Ext.isIE){el.setWidth(this.minWidth);var t=el.dom.offsetWidth;el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));}}},delayAutoWidth:function(){if(this.rendered){if(!this.awTask){this.awTask=new Ext.util.DelayedTask(this.autoWidth,this);}this.awTask.delay(20);}},findTargetItem:function(e){var t=e.getTarget(".x-menu-list-item",this.ul,true);if(t&&t.menuItemId){return this.items.get(t.menuItemId);}},onClick:function(e){var t;if(t=this.findTargetItem(e)){t.onClick(e);this.fireEvent("click",this,t,e);}},setActiveItem:function(_f,_10){if(_f!=this.activeItem){if(this.activeItem){this.activeItem.deactivate();}this.activeItem=_f;_f.activate(_10);}else{if(_10){_f.expandMenu();}}},tryActivate:function(_11,_12){var _13=this.items;for(var i=_11,len=_13.length;i>=0&&i<len;i+=_12){var _16=_13.get(i);if(!_16.disabled&&_16.canActivate){this.setActiveItem(_16,false);return _16;}}return false;},onMouseOver:function(e){var t;if(t=this.findTargetItem(e)){if(t.canActivate&&!t.disabled){this.setActiveItem(t,true);}}this.fireEvent("mouseover",this,e,t);},onMouseOut:function(e){var t;if(t=this.findTargetItem(e)){if(t==this.activeItem&&t.shouldDeactivate(e)){this.activeItem.deactivate();delete this.activeItem;}}this.fireEvent("mouseout",this,e,t);},isVisible:function(){return this.el&&this.el.isVisible();},show:function(el,pos,_1d){this.parentMenu=_1d;if(!this.el){this.render();}this.fireEvent("beforeshow",this);this.showAt(this.el.getAlignToXY(el,pos||this.defaultAlign),_1d,false);},showAt:function(xy,_1f,_20){this.parentMenu=_1f;if(!this.el){this.render();}if(_20!==false){this.fireEvent("beforeshow",this);}this.el.setXY(xy);this.el.show();this.focusEl.focus.defer(50,this.focusEl);this.fireEvent("show",this);},hide:function(_21){if(this.el&&this.isVisible()){this.fireEvent("beforehide",this);if(this.activeItem){this.activeItem.deactivate();this.activeItem=null;}this.el.hide();this.fireEvent("hide",this);}if(_21===true&&this.parentMenu){this.parentMenu.hide(true);}},add:function(){var a=arguments,l=a.length,_24;for(var i=0;i<l;i++){var el=a[i];if(el.render){_24=this.addItem(el);}else{if(typeof el=="string"){if(el=="separator"||el=="-"){_24=this.addSeparator();}else{_24=this.addText(el);}}else{if(el.tagName||el.el){_24=this.addElement(el);}else{if(typeof el=="object"){_24=this.addMenuItem(el);}}}}}return _24;},getEl:function(){if(!this.el){this.render();}return this.el;},addSeparator:function(){return this.addItem(new Ext.menu.Separator());},addElement:function(el){return this.addItem(new Ext.menu.BaseItem(el));},addItem:function(_28){this.items.add(_28);if(this.ul){var li=document.createElement("li");li.className="x-menu-list-item";this.ul.dom.appendChild(li);_28.render(li,this);this.delayAutoWidth();}return _28;},addMenuItem:function(_2a){if(!(_2a instanceof Ext.menu.Item)){_2a=new Ext.menu.Item(_2a);}return this.addItem(_2a);},addText:function(_2b){return this.addItem(new Ext.menu.TextItem(_2b));},insert:function(_2c,_2d){this.items.insert(_2c,_2d);if(this.ul){var li=document.createElement("li");li.className="x-menu-list-item";this.ul.dom.insertBefore(li,this.ul.dom.childNodes[_2c]);_2d.render(li,this);this.delayAutoWidth();}return _2d;},remove:function(_2f){this.items.removeKey(_2f.id);_2f.destroy();},removeAll:function(){var f;while(f=this.items.first()){this.remove(f);}}});Ext.menu.MenuNav=function(_31){Ext.menu.MenuNav.superclass.constructor.call(this,_31.el);this.scope=this.menu=_31;};Ext.extend(Ext.menu.MenuNav,Ext.KeyNav,{doRelay:function(e,h){var k=e.getKey();if(!this.menu.activeItem&&e.isNavKeyPress()&&k!=e.SPACE&&k!=e.RETURN){this.menu.tryActivate(0,1);return false;}return h.call(this.scope||this,e,this.menu);},up:function(e,m){if(!m.tryActivate(m.items.indexOf(m.activeItem)-1,-1)){m.tryActivate(m.items.length-1,-1);}},down:function(e,m){if(!m.tryActivate(m.items.indexOf(m.activeItem)+1,1)){m.tryActivate(0,1);}},right:function(e,m){if(m.activeItem){m.activeItem.expandMenu(true);}},left:function(e,m){m.hide();if(m.parentMenu&&m.parentMenu.activeItem){m.parentMenu.activeItem.activate();}},enter:function(e,m){if(m.activeItem){e.stopPropagation();m.activeItem.onClick(e);m.fireEvent("click",this,m.activeItem);return true;}}});
+
+Ext.menu.MenuMgr=function(){var _1,_2,_3={};function init(){_1={},_2=new Ext.util.MixedCollection();Ext.get(document).addKeyListener(27,function(){if(_2.length>0){hideAll();}});}function hideAll(){if(_2.length>0){var c=_2.clone();c.each(function(m){m.hide();});}}function onHide(m){_2.remove(m);if(_2.length<1){Ext.get(document).un("mousedown",onMouseDown);}}function onShow(m){var _8=_2.last();_2.add(m);if(_2.length==1){Ext.get(document).on("mousedown",onMouseDown);}if(m.parentMenu){m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"),10)+3);m.parentMenu.activeChild=m;}else{if(_8&&_8.isVisible()){m.getEl().setZIndex(parseInt(_8.getEl().getStyle("z-index"),10)+3);}}}function onBeforeHide(m){if(m.activeChild){m.activeChild.hide();}if(m.autoHideTimer){clearTimeout(m.autoHideTimer);delete m.autoHideTimer;}}function onBeforeShow(m){var pm=m.parentMenu;if(!pm&&!m.allowOtherMenus){hideAll();}else{if(pm&&pm.activeChild){pm.activeChild.hide();}}}function onMouseDown(e){if(_2.length>0&&!e.getTarget(".x-menu")){hideAll();}}function onBeforeCheck(mi,_e){if(_e){var g=_3[mi.group];for(var i=0,l=g.length;i<l;i++){if(g[i]!=mi){g[i].setChecked(false);}}}}return {hideAll:function(){hideAll();},register:function(_12){if(!_1){init();}_1[_12.id]=_12;_12.on("beforehide",onBeforeHide);_12.on("hide",onHide);_12.on("beforeshow",onBeforeShow);_12.on("show",onShow);var g=_12.group;if(g&&_12.events["checkchange"]){if(!_3[g]){_3[g]=[];}_3[g].push(_12);_12.on("checkchange",onCheck);}},get:function(_14){if(typeof _14=="string"){return _1[_14];}else{if(_14.events){return _14;}else{return new Ext.menu.Menu(_14);}}},unregister:function(_15){delete _1[_15.id];_15.un("beforehide",onBeforeHide);_15.un("hide",onHide);_15.un("beforeshow",onBeforeShow);_15.un("show",onShow);var g=_15.group;if(g&&_15.events["checkchange"]){_3[g].remove(_15);_15.un("checkchange",onCheck);}},registerCheckable:function(_17){var g=_17.group;if(g){if(!_3[g]){_3[g]=[];}_3[g].push(_17);_17.on("beforecheckchange",onBeforeCheck);}},unregisterCheckable:function(_19){var g=_19.group;if(g){_3[g].remove(_19);_19.un("beforecheckchange",onBeforeCheck);}}};}();
+
+Ext.menu.BaseItem=function(_1){Ext.menu.BaseItem.superclass.constructor.call(this,_1);this.addEvents({click:true,activate:true,deactivate:true});if(this.handler){this.on("click",this.handler,this.scope,true);}};Ext.extend(Ext.menu.BaseItem,Ext.Component,{canActivate:false,activeClass:"x-menu-item-active",hideOnClick:true,hideDelay:100,ctype:"Ext.menu.BaseItem",actionMode:"container",render:function(_2,_3){this.parentMenu=_3;Ext.menu.BaseItem.superclass.render.call(this,_2);this.container.menuItemId=this.id;},onRender:function(_4){this.el=Ext.get(this.el);_4.dom.appendChild(this.el.dom);},onClick:function(e){if(!this.disabled&&this.fireEvent("click",this,e)!==false&&this.parentMenu.fireEvent("itemclick",this,e)!==false){this.handleClick(e);}else{e.stopEvent();}},activate:function(){if(this.disabled){return false;}var li=this.container;li.addClass(this.activeClass);this.region=li.getRegion().adjust(2,2,-2,-2);this.fireEvent("activate",this);return true;},deactivate:function(){this.container.removeClass(this.activeClass);this.fireEvent("deactivate",this);},shouldDeactivate:function(e){return !this.region||!this.region.contains(e.getPoint());},handleClick:function(e){if(this.hideOnClick){this.parentMenu.hide.defer(this.hideDelay,this.parentMenu,[true]);}},expandMenu:function(_9){},hideMenu:function(){}});
+
+Ext.menu.TextItem=function(_1){this.text=_1;Ext.menu.TextItem.superclass.constructor.call(this);};Ext.extend(Ext.menu.TextItem,Ext.menu.BaseItem,{hideOnClick:false,itemCls:"x-menu-text",onRender:function(){var s=document.createElement("span");s.className=this.itemCls;s.innerHTML=this.text;this.el=s;Ext.menu.TextItem.superclass.onRender.apply(this,arguments);}});
+
+Ext.menu.Separator=function(_1){Ext.menu.Separator.superclass.constructor.call(this,_1);};Ext.extend(Ext.menu.Separator,Ext.menu.BaseItem,{itemCls:"x-menu-sep",hideOnClick:false,onRender:function(li){var s=document.createElement("span");s.className=this.itemCls;s.innerHTML="&#160;";this.el=s;li.addClass("x-menu-sep-li");Ext.menu.Separator.superclass.onRender.apply(this,arguments);}});
+
+Ext.menu.Item=function(_1){Ext.menu.Item.superclass.constructor.call(this,_1);if(this.menu){this.menu=Ext.menu.MenuMgr.get(this.menu);}};Ext.extend(Ext.menu.Item,Ext.menu.BaseItem,{itemCls:"x-menu-item",canActivate:true,ctype:"Ext.menu.Item",onRender:function(_2){var el=document.createElement("a");el.hideFocus=true;el.unselectable="on";el.href=this.href||"#";if(this.hrefTarget){el.target=this.hrefTarget;}el.className=this.itemCls+(this.menu?" x-menu-item-arrow":"")+(this.cls?" "+this.cls:"");el.innerHTML=String.format("<img src=\"{0}\" class=\"x-menu-item-icon\">{1}",this.icon||Ext.BLANK_IMAGE_URL,this.text);this.el=el;Ext.menu.Item.superclass.onRender.call(this,_2);},setText:function(_4){this.text=_4;if(this.rendered){this.el.update(String.format("<img src=\"{0}\" class=\"x-menu-item-icon\">{1}",this.icon||Ext.BLANK_IMAGE_URL,this.text));this.parentMenu.autoWidth();}},handleClick:function(e){if(!this.href){e.stopEvent();}Ext.menu.Item.superclass.handleClick.apply(this,arguments);},activate:function(_6){if(Ext.menu.Item.superclass.activate.apply(this,arguments)){this.focus();if(_6){this.expandMenu();}}return true;},shouldDeactivate:function(e){if(Ext.menu.Item.superclass.shouldDeactivate.call(this,e)){if(this.menu&&this.menu.isVisible()){return !this.menu.getEl().getRegion().contains(e.getPoint());}return true;}return false;},deactivate:function(){Ext.menu.Item.superclass.deactivate.apply(this,arguments);this.hideMenu();},expandMenu:function(_8){if(!this.disabled&&this.menu){if(!this.menu.isVisible()){this.menu.show(this.container,this.parentMenu.subMenuAlign||"tl-tr?",this.parentMenu);}if(_8){this.menu.tryActivate(0,1);}}},hideMenu:function(){if(this.menu&&this.menu.isVisible()){this.menu.hide();}}});
+
+Ext.menu.CheckItem=function(_1){Ext.menu.CheckItem.superclass.constructor.call(this,_1);this.addEvents({"beforecheckchange":true,"checkchange":true});if(this.checkHandler){this.on("checkchange",this.checkHandler,this.scope);}};Ext.extend(Ext.menu.CheckItem,Ext.menu.Item,{itemCls:"x-menu-item x-menu-check-item",groupClass:"x-menu-group-item",checked:false,ctype:"Ext.menu.CheckItem",onRender:function(c){Ext.menu.CheckItem.superclass.onRender.apply(this,arguments);if(this.group){this.el.addClass(this.groupClass);}Ext.menu.MenuMgr.registerCheckable(this);if(this.checked){this.checked=false;this.setChecked(true,true);}},destroy:function(){if(this.rendered){Ext.menu.MenuMgr.unregisterCheckable(this);}Ext.menu.CheckItem.superclass.destroy.apply(this,arguments);},setChecked:function(_3,_4){if(this.checked!=_3&&this.fireEvent("beforecheckchange",this,_3)!==false){if(this.container){this.container[_3?"addClass":"removeClass"]("x-menu-item-checked");}this.checked=_3;if(_4!==true){this.fireEvent("checkchange",this,_3);}}},handleClick:function(e){if(!this.disabled&&!(this.checked&&this.group)){this.setChecked(!this.checked);}Ext.menu.CheckItem.superclass.handleClick.apply(this,arguments);}});
+
+Ext.menu.Adapter=function(_1,_2){Ext.menu.Adapter.superclass.constructor.call(this,_2);this.component=_1;};Ext.extend(Ext.menu.Adapter,Ext.menu.BaseItem,{canActivate:true,onRender:function(_3){this.component.render(_3);this.el=this.component.getEl();},activate:function(){if(this.disabled){return false;}this.component.focus();this.fireEvent("activate",this);return true;},deactivate:function(){this.fireEvent("deactivate",this);},disable:function(){this.component.disable();Ext.menu.Adapter.superclass.disable.call(this);},enable:function(){this.component.enable();Ext.menu.Adapter.superclass.enable.call(this);}});
+
+Ext.menu.DateItem=function(_1){Ext.menu.DateItem.superclass.constructor.call(this,new Ext.DatePicker(_1),_1);this.picker=this.component;this.addEvents({select:true});this.picker.on("render",function(_2){_2.getEl().swallowEvent("click");_2.container.addClass("x-menu-date-item");});this.picker.on("select",this.onSelect,this);};Ext.extend(Ext.menu.DateItem,Ext.menu.Adapter,{onSelect:function(_3,_4){this.fireEvent("select",this,_4,_3);Ext.menu.DateItem.superclass.handleClick.call(this);}});
+
+Ext.menu.ColorItem=function(_1){Ext.menu.ColorItem.superclass.constructor.call(this,new Ext.ColorPalette(_1),_1);this.palette=this.component;this.relayEvents(this.palette,["select"]);if(this.selectHandler){this.on("select",this.selectHandler,this.scope);}};Ext.extend(Ext.menu.ColorItem,Ext.menu.Adapter);
+
+Ext.menu.DateMenu=function(_1){Ext.menu.DateMenu.superclass.constructor.call(this,_1);this.plain=true;var di=new Ext.menu.DateItem(_1);this.add(di);this.picker=di.picker;this.relayEvents(di,["select"]);};Ext.extend(Ext.menu.DateMenu,Ext.menu.Menu);
+
+Ext.menu.ColorMenu=function(_1){Ext.menu.ColorMenu.superclass.constructor.call(this,_1);this.plain=true;var ci=new Ext.menu.ColorItem(_1);this.add(ci);this.palette=ci.palette;this.relayEvents(ci,["select"]);};Ext.extend(Ext.menu.ColorMenu,Ext.menu.Menu);
+
+Ext.form.Field=function(_1){Ext.form.Field.superclass.constructor.call(this,_1);this.addEvents({focus:true,blur:true,specialkey:true,change:true,invalid:true,valid:true});};Ext.extend(Ext.form.Field,Ext.Component,{invalidClass:"x-form-invalid",invalidText:"The value in this field is invalid",focusClass:"x-form-focus",validationEvent:"keyup",validationDelay:250,defaultAutoCreate:{tag:"input",type:"text",size:"20",autocomplete:"off"},fieldClass:"x-form-field",msgTarget:"qtip",msgFx:"normal",inputType:undefined,isFormField:true,hasFocus:false,getName:function(){return this.rendered&&this.el.dom.name?this.el.dom.name:(this.hiddenName||"");},applyTo:function(_2){this.target=_2;this.el=Ext.get(_2);this.render(this.el.dom.parentNode);return this;},onRender:function(ct){if(this.el){this.el=Ext.get(this.el);if(!this.target){ct.dom.appendChild(this.el.dom);}}else{var _4=this.getAutoCreate();if(!_4.name){_4.name=this.name||this.id;}if(this.inputType){_4.type=this.inputType;}if(this.tabIndex!==undefined){_4.tabIndex=this.tabIndex;}this.el=ct.createChild(_4);}var _5=this.el.dom.type;if(_5){if(_5=="password"){_5="text";}this.el.addClass("x-form-"+_5);}if(!this.customSize&&(this.width||this.height)){this.setSize(this.width||"",this.height||"");}if(this.style){this.el.applyStyles(this.style);delete this.style;}if(this.readOnly){this.el.dom.readOnly=true;}this.el.addClass([this.fieldClass,this.cls]);this.initValue();},initValue:function(){if(this.value!==undefined){this.setValue(this.value);}else{if(this.el.dom.value.length>0){this.setValue(this.el.dom.value);}}},afterRender:function(){this.initEvents();},fireKey:function(e){if(e.isNavKeyPress()){this.fireEvent("specialkey",this,e);}},reset:function(){this.setValue(this.originalValue);this.clearInvalid();},initEvents:function(){this.el.on(Ext.isIE?"keydown":"keypress",this.fireKey,this);this.el.on("focus",this.onFocus,this);this.el.on("blur",this.onBlur,this);this.originalValue=this.getValue();},onFocus:function(){if(!Ext.isOpera){this.el.addClass(this.focusClass);}this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this);},onBlur:function(){this.el.removeClass(this.focusClass);this.hasFocus=false;if(this.validationEvent!="blur"){this.validate();}var v=this.getValue();if(v!=this.startValue){this.fireEvent("change",this,v,this.startValue);}this.fireEvent("blur",this);},setSize:function(w,h){if(!this.rendered||!this.el){this.width=w;this.height=h;return;}if(w){w=this.adjustWidth(this.el.dom.tagName,w);this.el.setWidth(w);}if(h){this.el.setHeight(h);}var h=this.el.dom.offsetHeight;},isValid:function(){return this.validateValue(this.getRawValue());},validate:function(){if(this.validateValue(this.getRawValue())){this.clearInvalid();return true;}return false;},validateValue:function(_a){return true;},markInvalid:function(_b){if(!this.rendered){return;}this.el.addClass(this.invalidClass);_b=_b||this.invalidText;switch(this.msgTarget){case "qtip":this.el.dom.qtip=_b;this.el.dom.qclass="x-form-invalid-tip";break;case "title":this.el.dom.title=_b;break;case "under":if(!this.errorEl){var _c=this.el.findParent(".x-form-element",5,true);this.errorEl=_c.createChild({cls:"x-form-invalid-msg"});this.errorEl.setWidth(_c.getWidth(true)-20);}this.errorEl.update(_b);Ext.form.Field.msgFx[this.msgFx].show(this.errorEl,this);break;case "side":if(!this.errorIcon){var _c=this.el.findParent(".x-form-element",5,true);this.errorIcon=_c.createChild({cls:"x-form-invalid-icon"});}this.alignErrorIcon();this.errorIcon.dom.qtip=_b;this.errorIcon.dom.qclass="x-form-invalid-tip";this.errorIcon.show();break;default:var t=Ext.getDom(this.msgTarget);t.innerHTML=_b;t.style.display=this.msgDisplay;break;}this.fireEvent("invalid",this,_b);},alignErrorIcon:function(){this.errorIcon.alignTo(this.el,"tl-tr",[2,0]);},clearInvalid:function(){if(!this.rendered){return;}this.el.removeClass(this.invalidClass);switch(this.msgTarget){case "qtip":this.el.dom.qtip="";break;case "title":this.el.dom.title="";break;case "under":if(this.errorEl){Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl,this);}break;case "side":if(this.errorIcon){this.errorIcon.dom.qtip="";this.errorIcon.hide();}break;default:var t=Ext.getDom(this.msgTarget);t.innerHTML="";t.style.display="none";break;}this.fireEvent("valid",this);},getRawValue:function(){return this.el.getValue();},getValue:function(){var v=this.el.getValue();if(v==this.emptyText||v===undefined){v="";}return v;},setRawValue:function(v){return this.el.dom.value=v;},setValue:function(v){this.value=v;if(this.rendered){this.el.dom.value=v;this.validate();}},adjustWidth:function(tag,w){tag=tag.toLowerCase();if(typeof w=="number"&&Ext.isStrict&&!Ext.isSafari){if(Ext.isIE&&(tag=="input"||tag=="textarea")){if(tag=="input"){return w+2;}if(tag="textarea"){return w-2;}}else{if(Ext.isGecko&&tag=="textarea"){return w-6;}else{if(Ext.isOpera){if(tag=="input"){return w+2;}if(tag="textarea"){return w-2;}}}}}return w;}});Ext.form.Field.msgFx={normal:{show:function(_14,f){_14.setDisplayed("block");},hide:function(_16,f){_16.setDisplayed(false).update("");}},slide:{show:function(_18,f){_18.slideIn("t",{stopFx:true});},hide:function(_1a,f){_1a.slideOut("t",{stopFx:true,useDisplay:true});}},slideRight:{show:function(_1c,f){_1c.fixDisplay();_1c.alignTo(f.el,"tl-tr");_1c.slideIn("l",{stopFx:true});},hide:function(_1e,f){_1e.slideOut("l",{stopFx:true,useDisplay:true});}}};
+
+Ext.form.TextField=function(_1){Ext.form.TextField.superclass.constructor.call(this,_1);this.addEvents({autosize:true});};Ext.extend(Ext.form.TextField,Ext.form.Field,{grow:false,growMin:30,growMax:800,vtype:null,maskRe:null,disableKeyFilter:false,allowBlank:true,minLength:0,maxLength:Number.MAX_VALUE,minLengthText:"The minimum length for this field is {0}",maxLengthText:"The maximum length for this field is {0}",selectOnFocus:false,blankText:"This field is required",validator:null,regex:null,regexText:"",emptyText:null,emptyClass:"x-form-empty-field",initEvents:function(){Ext.form.TextField.superclass.initEvents.call(this);if(this.validationEvent=="keyup"){this.validationTask=new Ext.util.DelayedTask(this.validate,this);this.el.on("keyup",this.filterValidation,this);}else{if(this.validationEvent!==false){this.el.on(this.validationEvent,this.validate,this,{buffer:this.validationDelay});}}if(this.selectOnFocus||this.emptyText){this.on("focus",this.preFocus,this);if(this.emptyText){this.on("blur",this.postBlur,this);if(!this.value&&this.getRawValue().length<1){this.setRawValue(this.emptyText);this.el.addClass(this.emptyClass);}}}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Ext.form.VTypes[this.vtype+"Mask"]))){this.el.on("keypress",this.filterKeys,this);}if(this.grow){this.el.on("keyup",this.onKeyUp,this,{buffer:50});this.el.on("click",this.autoSize,this);}},filterValidation:function(e){if(!e.isNavKeyPress()){this.validationTask.delay(this.validationDelay);}},onKeyUp:function(e){if(!e.isNavKeyPress()){this.autoSize();}},reset:function(){Ext.form.TextField.superclass.reset.call(this);if(this.emptyText&&this.getRawValue().length<1){this.setRawValue(this.emptyText);this.el.addClass(this.emptyClass);}},preFocus:function(){if(this.emptyText){if(this.getRawValue()==this.emptyText){this.setRawValue("");}this.el.removeClass(this.emptyClass);}if(this.selectOnFocus){this.el.dom.select();}},postBlur:function(){if(this.emptyText&&this.getRawValue().length<1){this.setRawValue(this.emptyText);this.el.addClass(this.emptyClass);}},filterKeys:function(e){var k=e.getKey();if(!Ext.isIE&&(e.isNavKeyPress()||k==e.BACKSPACE||(k==e.DELETE&&e.button==-1))){return;}var c=e.getCharCode();if(!this.maskRe.test(String.fromCharCode(c)||"")){e.stopEvent();}},setValue:function(v){if(this.emptyText&&v!==undefined&&v!==null&&v!==""){this.el.removeClass(this.emptyClass);}Ext.form.TextField.superclass.setValue.apply(this,arguments);},validateValue:function(_8){if(_8.length<1||_8===this.emptyText){if(this.allowBlank){this.clearInvalid();return true;}else{this.markInvalid(this.blankText);return false;}}if(_8.length<this.minLength){this.markInvalid(String.format(this.minLengthText,this.minLength));return false;}if(_8.length>this.maxLength){this.markInvalid(String.format(this.maxLengthText,this.maxLength));return false;}if(this.vtype){var vt=Ext.form.VTypes;if(!vt[this.vtype](_8)){this.markInvalid(this.vtypeText||vt[this.vtype+"Text"]);return false;}}if(typeof this.validator=="function"){var _a=this.validator(_8);if(_a!==true){this.markInvalid(_a);return false;}}if(this.regex&&!this.regex.test(_8)){this.markInvalid(this.regexText);return false;}return true;},selectText:function(_b,_c){var v=this.getRawValue();if(v.length>0){_b=_b===undefined?0:_b;_c=_c===undefined?v.length:_c;var d=this.el.dom;if(d.setSelectionRange){d.setSelectionRange(_b,_c);}else{if(d.createTextRange){var _f=d.createTextRange();_f.moveStart("character",_b);_f.moveEnd("character",v.length-_c);_f.select();}}}},autoSize:function(){if(!this.grow||!this.rendered){return;}if(!this.metrics){this.metrics=Ext.util.TextMetrics.createInstance(this.el);}var el=this.el;var v=el.dom.value+"&#160;";var w=Math.min(this.growMax,Math.max(this.metrics.getWidth(v)+10,this.growMin));this.el.setWidth(w);this.fireEvent("autosize",this,w);}});
+
+Ext.form.TriggerField=function(_1){Ext.form.TriggerField.superclass.constructor.call(this,_1);this.mimicing=false;this.on("disable",this.disableWrapper,this);this.on("enable",this.enableWrapper,this);};Ext.extend(Ext.form.TriggerField,Ext.form.TextField,{defaultAutoCreate:{tag:"input",type:"text",size:"16",autocomplete:"off"},hideTrigger:false,autoSize:Ext.emptyFn,customSize:true,setSize:function(w,h){if(!this.wrap){this.width=w;this.height=h;return;}if(w){var _4=w;w=w-this.trigger.getWidth();Ext.form.TriggerField.superclass.setSize.call(this,w,h);this.wrap.setWidth(_4);if(this.onResize){this.onResize(_4,h);}}else{Ext.form.TriggerField.superclass.setSize.call(this,w,h);this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());}},alignErrorIcon:function(){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0]);},onRender:function(ct){Ext.form.TriggerField.superclass.onRender.call(this,ct);this.wrap=this.el.wrap({cls:"x-form-field-wrap"});this.trigger=this.wrap.createChild({tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.triggerClass});this.trigger.on("click",this.onTriggerClick,this,{preventDefault:true});this.trigger.addClassOnOver("x-form-trigger-over");this.trigger.addClassOnClick("x-form-trigger-click");if(this.hideTrigger){this.trigger.setDisplayed(false);}this.setSize(this.width||"",this.height||"");},onDestroy:function(){if(this.trigger){this.trigger.removeAllListeners();this.trigger.remove();}if(this.wrap){this.wrap.remove();}Ext.form.TriggerField.superclass.onDestroy.call(this);},onFocus:function(){Ext.form.TriggerField.superclass.onFocus.call(this);if(!this.mimicing){this.mimicing=true;Ext.get(document).on("mousedown",this.mimicBlur,this);this.el.on("keydown",this.checkTab,this);}},checkTab:function(e){if(e.getKey()==e.TAB){this.triggerBlur();}},onBlur:function(){},mimicBlur:function(e,t){if(!this.wrap.contains(t)&&this.validateBlur()){this.triggerBlur();}},triggerBlur:function(){this.mimicing=false;Ext.get(document).un("mousedown",this.mimicBlur);this.el.un("keydown",this.checkTab,this);Ext.form.TriggerField.superclass.onBlur.call(this);},validateBlur:function(e,t){return true;},disableWrapper:function(){if(this.wrap){this.wrap.addClass("x-item-disabled");}},enableWrapper:function(){if(this.wrap){this.wrap.removeClass("x-item-disabled");}},onShow:function(){if(this.wrap){this.wrap.dom.style.display="";this.wrap.dom.style.visibility="visible";}},onHide:function(){this.wrap.dom.style.display="none";},onTriggerClick:Ext.emptyFn});
+
+Ext.form.TextArea=function(_1){Ext.form.TextArea.superclass.constructor.call(this,_1);if(this.minHeight!==undefined){this.growMin=this.minHeight;}if(this.maxHeight!==undefined){this.growMax=this.maxHeight;}};Ext.extend(Ext.form.TextArea,Ext.form.TextField,{growMin:60,growMax:1000,preventScrollbars:false,onRender:function(ct){if(!this.el){this.defaultAutoCreate={tag:"textarea",style:"width:300px;height:60px;",autocomplete:"off"};}Ext.form.TextArea.superclass.onRender.call(this,ct);if(this.grow){this.textSizeEl=Ext.DomHelper.append(document.body,{tag:"pre",cls:"x-form-grow-sizer"});if(this.preventScrollbars){this.el.setStyle("overflow","hidden");}this.el.setHeight(this.growMin);}},onKeyUp:function(e){if(!e.isNavKeyPress()||e.getKey()==e.ENTER){this.autoSize();}},autoSize:function(){if(!this.grow||!this.textSizeEl){return;}var el=this.el;var v=el.dom.value;var ts=this.textSizeEl;Ext.fly(ts).setWidth(this.el.getWidth());if(v.length<1){v="&#160;&#160;";}else{v+="&#160;\n&#160;";}if(Ext.isIE){v=v.replace(/\n/g,"<br />");}ts.innerHTML=v;var h=Math.min(this.growMax,Math.max(ts.offsetHeight,this.growMin));this.el.setHeight(h);this.fireEvent("autosize",this,h);},setValue:function(v){Ext.form.TextArea.superclass.setValue.call(this,v);this.autoSize();}});
+
+Ext.form.NumberField=function(_1){Ext.form.NumberField.superclass.constructor.call(this,_1);};Ext.extend(Ext.form.NumberField,Ext.form.TextField,{fieldClass:"x-form-field x-form-num-field",allowDecimals:true,decimalSeparator:".",decimalPrecision:2,allowNegative:true,minValue:Number.NEGATIVE_INFINITY,maxValue:Number.MAX_VALUE,minText:"The minimum value for this field is {0}",maxText:"The maximum value for this field is {0}",nanText:"{0} is not a valid number",initEvents:function(){Ext.form.NumberField.superclass.initEvents.call(this);var _2="0123456789";if(this.allowDecimals){_2+=this.decimalSeparator;}if(this.allowNegative){_2+="-";}var _3=function(e){var k=e.getKey();if(!Ext.isIE&&(e.isNavKeyPress()||k==e.BACKSPACE||(k==e.DELETE&&e.button==-1))){return;}var c=e.getCharCode();if(_2.indexOf(String.fromCharCode(c))===-1){e.stopEvent();}};this.el.on("keypress",_3,this);},validateValue:function(_7){if(!Ext.form.NumberField.superclass.validateValue.call(this,_7)){return false;}if(_7.length<1){return true;}if(isNaN(_7)){this.markInvalid(String.format(this.nanText,_7));return false;}var _8=this.parseValue(_7);if(_8<this.minValue){this.markInvalid(String.format(this.minText,this.minValue));return false;}if(_8>this.maxValue){this.markInvalid(String.format(this.maxText,this.maxValue));return false;}return true;},parseValue:function(_9){return parseFloat(String(_9).replace(this.decimalSeparator,"."));},fixPrecision:function(_a){if(!this.allowDecimals||this.decimalPrecision==-1||isNaN(_a)||_a==0||!_a){return _a;}var _b=Math.pow(10,this.decimalPrecision+1);var _c=this.decimalPrecisionFcn(_a*_b);_c=this.decimalPrecisionFcn(_c/10);return _c/(_b/10);},decimalPrecisionFcn:function(v){return Math.floor(v);}});
+
+Ext.form.DateField=function(_1){Ext.form.DateField.superclass.constructor.call(this,_1);if(typeof this.minValue=="string"){this.minValue=this.parseDate(this.minValue);}if(typeof this.maxValue=="string"){this.maxValue=this.parseDate(this.maxValue);}this.ddMatch=null;if(this.disabledDates){var dd=this.disabledDates;var re="(?:";for(var i=0;i<dd.length;i++){re+=dd[i];if(i!=dd.length-1){re+="|";}}this.ddMatch=new RegExp(re+")");}};Ext.extend(Ext.form.DateField,Ext.form.TriggerField,{format:"m/d/y",disabledDays:null,disabledDaysText:"Disabled",disabledDates:null,disabledDatesText:"Disabled",minValue:null,maxValue:null,minText:"The date in this field must be after {0}",maxText:"The date in this field must be before {0}",invalidText:"{0} is not a valid date - it must be in the format {1}",triggerClass:"x-form-date-trigger",defaultAutoCreate:{tag:"input",type:"text",size:"10",autocomplete:"off"},validateValue:function(_5){_5=this.formatDate(_5);if(!Ext.form.DateField.superclass.validateValue.call(this,_5)){return false;}if(_5.length<1){return true;}var _6=_5;_5=this.parseDate(_5);if(!_5){this.markInvalid(String.format(this.invalidText,_6,this.format));return false;}var _7=_5.getTime();if(this.minValue&&_7<this.minValue.getTime()){this.markInvalid(String.format(this.minText,this.formatDate(this.minValue)));return false;}if(this.maxValue&&_7>this.maxValue.getTime()){this.markInvalid(String.format(this.maxText,this.formatDate(this.maxValue)));return false;}if(this.disabledDays){var _8=_5.getDay();for(var i=0;i<this.disabledDays.length;i++){if(_8===this.disabledDays[i]){this.markInvalid(this.disabledDaysText);return false;}}}var _a=this.formatDate(_5);if(this.ddMatch&&this.ddMatch.test(_a)){this.markInvalid(String.format(this.disabledDatesText,_a));return false;}return true;},validateBlur:function(){return !this.menu||!this.menu.isVisible();},getValue:function(){return this.parseDate(Ext.form.DateField.superclass.getValue.call(this))||"";},setValue:function(_b){Ext.form.DateField.superclass.setValue.call(this,this.formatDate(this.parseDate(_b)));},parseDate:function(_c){return (!_c||_c instanceof Date)?_c:Date.parseDate(_c,this.format);},formatDate:function(_d){return (!_d||!(_d instanceof Date))?_d:_d.dateFormat(this.format);},menuListeners:{select:function(m,d){this.setValue(d);},show:function(){this.onFocus();},hide:function(){this.focus();var ml=this.menuListeners;this.menu.un("select",ml.select,this);this.menu.un("show",ml.show,this);this.menu.un("hide",ml.hide,this);}},onTriggerClick:function(){if(this.disabled){return;}if(this.menu==null){this.menu=new Ext.menu.DateMenu();}Ext.apply(this.menu,{minDate:this.minValue,maxDate:this.maxValue,disabledDatesRE:this.ddMatch,disabledDatesText:this.disabledDatesText,disabledDays:this.disabledDays,disabledDaysText:this.disabledDaysText,format:this.format,minText:String.format(this.minText,this.formatDate(this.minValue)),maxText:String.format(this.maxText,this.formatDate(this.maxValue))});this.menu.on(Ext.apply({},this.menuListeners,{scope:this}));this.menu.picker.setValue(this.getValue()||new Date());this.menu.show(this.el,"tl-bl?");}});
+
+Ext.form.ComboBox=function(_1){Ext.form.ComboBox.superclass.constructor.call(this,_1);this.addEvents({"expand":true,"collapse":true,"beforeselect":true,"select":true,"beforequery":true});if(this.transform){var s=Ext.getDom(this.transform);if(!this.hiddenName){this.hiddenName=s.name;}if(!this.store){this.mode="local";var d=[],_4=s.options;for(var i=0,_6=_4.length;i<_6;i++){var o=_4[i];var _8=(Ext.isIE?o.getAttributeNode("value").specified:o.hasAttribute("value"))?o.value:o.text;if(o.selected){this.value=_8;}d.push([_8,o.text]);}this.store=new Ext.data.SimpleStore({"id":0,fields:["value","text"],data:d});this.valueField="value";this.displayField="text";}s.name=Ext.id();if(!this.lazyRender){this.target=true;this.el=Ext.DomHelper.insertBefore(s,this.autoCreate||this.defaultAutoCreate);s.parentNode.removeChild(s);this.render(this.el.parentNode);}else{s.parentNode.removeChild(s);}}this.selectedIndex=-1;if(this.mode=="local"){if(_1.queryDelay===undefined){this.queryDelay=10;}if(_1.minChars===undefined){this.minChars=0;}}};Ext.extend(Ext.form.ComboBox,Ext.form.TriggerField,{defaultAutoCreate:{tag:"input",type:"text",size:"24",autocomplete:"off"},listWidth:undefined,displayField:undefined,valueField:undefined,hiddenName:undefined,listClass:"",selectedClass:"x-combo-selected",triggerClass:"x-form-arrow-trigger",shadow:"sides",listAlign:"tl-bl?",maxHeight:300,triggerAction:"query",minChars:4,typeAhead:false,queryDelay:500,pageSize:0,selectOnFocus:false,queryParam:"query",loadingText:"Loading...",resizable:false,handleHeight:8,editable:true,allQuery:"",mode:"remote",minListWidth:70,forceSelection:false,typeAheadDelay:250,valueNotFoundText:undefined,onRender:function(ct){Ext.form.ComboBox.superclass.onRender.call(this,ct);if(this.hiddenName){this.hiddenField=this.el.insertSibling({tag:"input",type:"hidden",name:this.hiddenName,id:this.hiddenName},"before",true);this.hiddenField.value=this.hiddenValue!==undefined?this.hiddenValue:this.value!==undefined?this.value:"";this.el.dom.removeAttribute("name");}if(Ext.isGecko){this.el.dom.setAttribute("autocomplete","off");}var _a="x-combo-list";this.list=new Ext.Layer({shadow:this.shadow,cls:[_a,this.listClass].join(" "),constrain:false});this.list.setWidth(this.listWidth||Math.max(this.wrap.getWidth(),this.minListWidth));this.list.swallowEvent("mousewheel");this.assetHeight=0;if(this.title){this.header=this.list.createChild({cls:_a+"-hd",html:this.title});this.assetHeight+=this.header.getHeight();}this.innerList=this.list.createChild({cls:_a+"-inner"});this.innerList.on("mouseover",this.onViewOver,this);this.innerList.on("mousemove",this.onViewMove,this);if(this.pageSize){this.footer=this.list.createChild({cls:_a+"-ft"});this.pageTb=new Ext.PagingToolbar(this.footer,this.store,{pageSize:this.pageSize});this.assetHeight+=this.footer.getHeight();}if(!this.tpl){this.tpl="<div class=\""+_a+"-item\">{"+this.displayField+"}</div>";}this.view=new Ext.View(this.innerList,this.tpl,{singleSelect:true,store:this.store,selectedClass:this.selectedClass});this.view.on("click",this.onViewClick,this);this.store.on("beforeload",this.onBeforeLoad,this);this.store.on("load",this.onLoad,this);this.store.on("loadexception",this.collapse,this);if(this.resizable){this.resizer=new Ext.Resizable(this.list,{pinned:true,handles:"se"});this.resizer.on("resize",function(r,w,h){this.maxHeight=h-this.handleHeight-this.list.getFrameWidth("tb")-this.assetHeight;this.listWidth=w;this.restrictHeight();},this);this[this.pageSize?"footer":"innerList"].setStyle("margin-bottom",this.handleHeight+"px");}if(!this.editable){this.editable=true;this.setEditable(false);}},initEvents:function(){Ext.form.ComboBox.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{"up":function(e){this.inKeyMode=true;this.selectPrev();},"down":function(e){if(!this.isExpanded()){this.onTriggerClick();}else{this.inKeyMode=true;this.selectNext();}},"enter":function(e){this.onViewClick();},"esc":function(e){this.collapse();},"tab":function(e){this.onViewClick(false);return true;},scope:this,doRelay:function(foo,bar,_15){if(_15=="down"||this.scope.isExpanded()){return Ext.KeyNav.prototype.doRelay.apply(this,arguments);}return true;}});this.queryDelay=Math.max(this.queryDelay||10,this.mode=="local"?10:250);this.dqTask=new Ext.util.DelayedTask(this.initQuery,this);if(this.typeAhead){this.taTask=new Ext.util.DelayedTask(this.onTypeAhead,this);}if(this.editable!==false){this.el.on("keyup",this.onKeyUp,this);}if(this.forceSelection){this.on("blur",this.doForce,this);}},onDestroy:function(){if(this.view){this.view.setStore(null);this.view.el.removeAllListeners();this.view.el.remove();this.view.purgeListeners();}if(this.list){this.list.destroy();}if(this.store){this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("loadexception",this.collapse,this);}Ext.form.ComboBox.superclass.onDestroy.call(this);},fireKey:function(e){if(e.isNavKeyPress()&&!this.list.isVisible()){this.fireEvent("specialkey",this,e);}},onResize:function(w,h){if(this.list&&this.listWidth===undefined){this.list.setWidth(Math.max(w,this.minListWidth));}},setEditable:function(_19){if(_19==this.editable){return;}this.editable=_19;if(!_19){this.el.dom.setAttribute("readOnly",true);this.el.on("mousedown",this.onTriggerClick,this);this.el.addClass("x-combo-noedit");}else{this.el.dom.setAttribute("readOnly",false);this.el.un("mousedown",this.onTriggerClick,this);this.el.removeClass("x-combo-noedit");}},onBeforeLoad:function(){if(!this.hasFocus){return;}this.innerList.update(this.loadingText?"<div class=\"loading-indicator\">"+this.loadingText+"</div>":"");this.restrictHeight();this.selectedIndex=-1;},onLoad:function(){if(!this.hasFocus){return;}if(this.store.getCount()>0){this.expand();this.restrictHeight();if(this.lastQuery==this.allQuery){if(this.editable){this.el.dom.select();}if(!this.selectByValue(this.value,true)){this.select(0,true);}}else{this.selectNext();if(this.typeAhead&&this.lastKey!=Ext.EventObject.BACKSPACE&&this.lastKey!=Ext.EventObject.DELETE){this.taTask.delay(this.typeAheadDelay);}}}else{this.onEmptyResults();}},onTypeAhead:function(){if(this.store.getCount()>0){var r=this.store.getAt(0);var _1b=r.data[this.displayField];var len=_1b.length;var _1d=this.getRawValue().length;if(_1d!=len){this.setRawValue(_1b);this.selectText(_1d,_1b.length);}}},onSelect:function(_1e,_1f){if(this.fireEvent("beforeselect",this,_1e,_1f)!==false){this.setValue(_1e.data[this.valueField||this.displayField]);this.collapse();this.fireEvent("select",this,_1e,_1f);}},getValue:function(){if(this.valueField){return typeof this.value!="undefined"?this.value:"";}else{return Ext.form.ComboBox.superclass.getValue.call(this);}},clearValue:function(){if(this.hiddenField){this.hiddenField.value="";}this.setRawValue("");this.lastSelectionText="";},setValue:function(v){var _21=v;if(this.valueField){var r=this.findRecord(this.valueField,v);if(r){_21=r.data[this.displayField];}else{if(this.valueNotFoundText){_21=this.valueNotFoundText;}}}this.lastSelectionText=_21;if(this.hiddenField){this.hiddenField.value=v;}Ext.form.ComboBox.superclass.setValue.call(this,_21);this.value=v;},findRecord:function(_23,_24){var _25;if(this.store.getCount()>0){this.store.each(function(r){if(r.data[_23]==_24){_25=r;return false;}});}return _25;},onViewMove:function(e,t){this.inKeyMode=false;},onViewOver:function(e,t){if(this.inKeyMode){return;}var _2b=this.view.findItemFromChild(t);if(_2b){var _2c=this.view.indexOf(_2b);this.select(_2c,false);}},onViewClick:function(_2d){var _2e=this.view.getSelectedIndexes()[0];var r=this.store.getAt(_2e);if(r){this.onSelect(r,_2e);}if(_2d!==false){this.el.focus();}},restrictHeight:function(){this.innerList.dom.style.height="";var _30=this.innerList.dom;var h=Math.max(_30.clientHeight,_30.offsetHeight,_30.scrollHeight);this.innerList.setHeight(h<this.maxHeight?"auto":this.maxHeight);this.list.beginUpdate();this.list.setHeight(this.innerList.getHeight()+this.list.getFrameWidth("tb")+(this.resizable?this.handleHeight:0)+this.assetHeight);this.list.alignTo(this.el,this.listAlign);this.list.endUpdate();},onEmptyResults:function(){this.collapse();},isExpanded:function(){return this.list.isVisible();},selectByValue:function(v,_33){if(v!==undefined&&v!==null){var r=this.findRecord(this.valueField||this.displayField,v);if(r){this.select(this.store.indexOf(r),_33);return true;}}return false;},select:function(_35,_36){this.selectedIndex=_35;this.view.select(_35);if(_36!==false){var el=this.view.getNode(_35);if(el){this.innerList.scrollChildIntoView(el);}}},selectNext:function(){var ct=this.store.getCount();if(ct>0){if(this.selectedIndex==-1){this.select(0);}else{if(this.selectedIndex<ct-1){this.select(this.selectedIndex+1);}}}},selectPrev:function(){var ct=this.store.getCount();if(ct>0){if(this.selectedIndex==-1){this.select(0);}else{if(this.selectedIndex!=0){this.select(this.selectedIndex-1);}}}},onKeyUp:function(e){if(this.editable!==false&&!e.isSpecialKey()){this.lastKey=e.getKey();this.dqTask.delay(this.queryDelay);}},validateBlur:function(){return !this.list||!this.list.isVisible();},initQuery:function(){this.doQuery(this.getRawValue());},doForce:function(){if(this.el.dom.value.length>0){this.el.dom.value=this.lastSelectionText===undefined?"":this.lastSelectionText;}},doQuery:function(q,_3c){if(q===undefined||q===null){q="";}var qe={query:q,forceAll:_3c,combo:this,cancel:false};if(this.fireEvent("beforequery",qe)===false||qe.cancel){return false;}q=qe.query;_3c=qe.forceAll;if(_3c===true||(q.length>=this.minChars)){if(this.lastQuery!=q){this.lastQuery=q;if(this.mode=="local"){this.selectedIndex=-1;if(_3c){this.store.clearFilter();}else{this.store.filter(this.displayField,q);}this.onLoad();}else{this.store.baseParams[this.queryParam]=q;this.store.load({params:this.getParams(q)});this.expand();}}else{this.selectedIndex=-1;this.onLoad();}}},getParams:function(q){var p={};if(this.pageSize){p.start=0;p.limit=this.pageSize;}return p;},collapse:function(){if(!this.isExpanded()){return;}this.list.hide();Ext.get(document).un("mousedown",this.collapseIf,this);this.fireEvent("collapse",this);},collapseIf:function(e){if(!e.within(this.wrap)&&!e.within(this.list)){this.collapse();}},expand:function(){if(this.isExpanded()){return;}this.list.alignTo(this.el,this.listAlign);this.list.show();Ext.get(document).on("mousedown",this.collapseIf,this);this.fireEvent("expand",this);},onTriggerClick:function(){if(this.disabled){return;}if(this.isExpanded()){this.collapse();this.el.focus();}else{this.hasFocus=true;this.doQuery(this.triggerAction=="all"?this.doQuery(this.allQuery,true):this.doQuery(this.getRawValue()));this.el.focus();}}});
+
+Ext.form.Checkbox=function(_1){Ext.form.Checkbox.superclass.constructor.call(this,_1);this.addEvents({check:true});};Ext.extend(Ext.form.Checkbox,Ext.form.Field,{focusClass:"x-form-check-focus",fieldClass:"x-form-field",checked:false,defaultAutoCreate:{tag:"input",type:"checkbox",autocomplete:"off"},boxLabel:undefined,setSize:function(w,h){if(!this.wrap){this.width=w;this.height=h;return;}this.wrap.setSize(w,h);if(!this.boxLabel){this.el.alignTo(this.wrap,"c-c");}},initEvents:function(){Ext.form.Checkbox.superclass.initEvents.call(this);this.el.on("click",this.onClick,this);this.el.on("change",this.onClick,this);},onRender:function(ct){Ext.form.Checkbox.superclass.onRender.call(this,ct);if(this.inputValue!==undefined){this.el.dom.value=this.inputValue;}this.wrap=this.el.wrap({cls:"x-form-check-wrap"});if(this.boxLabel){this.wrap.createChild({tag:"label",htmlFor:this.el.id,cls:"x-form-cb-label",html:this.boxLabel});}if(this.checked){this.setValue(true);}},initValue:Ext.emptyFn,getValue:function(){if(this.rendered){return this.el.dom.checked;}return false;},onClick:function(){if(this.el.dom.checked!=this.checked){this.setValue(this.el.dom.checked);}},setValue:function(v){this.checked=(v===true||v==="true"||v=="1");if(this.el&&this.el.dom){this.el.dom.checked=this.checked;}this.fireEvent("check",this,this.checked);}});
+
+Ext.form.Radio=function(){Ext.form.Radio.superclass.constructor.apply(this,arguments);};Ext.extend(Ext.form.Radio,Ext.form.Checkbox,{inputType:"radio"});
+
+Ext.form.BasicForm=function(el,_2){Ext.apply(this,_2);this.items=new Ext.util.MixedCollection(false,function(o){return o.id||(o.id=Ext.id());});this.addEvents({beforeaction:true,actionfailed:true,actioncomplete:true});if(el){this.initEl(el);}Ext.form.BasicForm.superclass.constructor.call(this);};Ext.extend(Ext.form.BasicForm,Ext.util.Observable,{timeout:30,activeAction:null,initEl:function(el){this.el=Ext.get(el);this.id=this.el.id||Ext.id();this.el.on("submit",this.onSubmit,this);this.el.addClass("x-form");},onSubmit:function(e){e.stopEvent();},isValid:function(){var _6=true;this.items.each(function(f){if(!f.validate()){_6=false;}});return _6;},doAction:function(_8,_9){if(typeof _8=="string"){_8=new Ext.form.Action.ACTION_TYPES[_8](this,_9);}if(this.fireEvent("beforeaction",this,_8)!==false){this.beforeAction(_8);_8.run.defer(100,_8);}},submit:function(_a){this.doAction("submit",_a);},load:function(_b){this.doAction("load",_b);},updateRecord:function(_c){_c.beginEdit();var fs=_c.fields;fs.each(function(f){var _f=this.fieldField(f.name);if(_f){_c.set(f.name,_f.getValue());}},this);_c.endEdit();},beforeAction:function(_10){var o=_10.options;if(o.waitMsg){Ext.MessageBox.wait(o.waitMsg,o.waitTitle||this.waitTitle||"Please Wait...");}},afterAction:function(_12,_13){this.activeAction=null;var o=_12.options;if(o.waitMsg){Ext.MessageBox.updateProgress(1);Ext.MessageBox.hide();}if(_13){if(o.reset){this.reset();}Ext.callback(o.success,o.scope,[this,_12]);this.fireEvent("actioncomplete",this,_12);}else{Ext.callback(o.failure,o.scope,[this,_12]);this.fireEvent("actionfailed",this,_12);}},findField:function(id){var _16=this.items.get(id);if(!_16){this.items.each(function(f){if(f.isFormField&&(f.dataIndex==id||f.id==id||f.getName()==id)){_16=f;return false;}});}return _16||null;},markInvalid:function(_18){if(_18 instanceof Array){for(var i=0,len=_18.length;i<len;i++){var _1b=_18[i];var f=this.findField(_1b.id);if(f){f.markInvalid(_1b.msg);}}}else{var _1d,id;for(id in _18){if(typeof _18[id]!="function"&&(_1d=this.findField(id))){_1d.markInvalid(_18[id]);}}}},setValues:function(_1f){if(_1f instanceof Array){for(var i=0,len=_1f.length;i<len;i++){var v=_1f[i];var f=this.findField(v.id);if(f){f.setValue(v.value);}}}else{var _24,id;for(id in _1f){if(typeof _1f[id]!="function"&&(_24=this.findField(id))){_24.setValue(_1f[id]);}}}},getValues:function(){var fs=Ext.lib.Ajax.serializeForm(this.el.dom);return Ext.urlDecode(fs);},clearInvalid:function(){this.items.each(function(f){f.clearInvalid();});},reset:function(){this.items.each(function(f){f.reset();});},add:function(){this.items.addAll(Array.prototype.slice.call(arguments,0));},remove:function(_29){this.items.remove(_29);},render:function(){this.items.each(function(f){if(f.isFormField&&!f.rendered&&document.getElementById(f.id)){f.applyTo(f.id);}});},applyToFields:function(o){this.items.each(function(f){Ext.apply(f,o);});},applyIfToFields:function(o){this.items.each(function(f){Ext.applyIf(f,o);});}});Ext.BasicForm=Ext.form.BasicForm;
+
+Ext.form.Form=function(_1){Ext.form.Form.superclass.constructor.call(this,null,_1);this.url=this.url||this.action;if(!this.root){this.root=new Ext.form.Layout(_1);}this.active=this.root;this.buttons=[];};Ext.extend(Ext.form.Form,Ext.form.BasicForm,{buttonPosition:"bottom",buttonAlign:"center",minButtonWidth:75,labelAlign:"left",column:function(c){var _3=new Ext.form.Column(c);this.start(_3);if(arguments.length>1){this.add.apply(this,Array.prototype.slice.call(arguments,1));this.end();}return _3;},fieldset:function(c){var fs=new Ext.form.FieldSet(c);this.start(fs);if(arguments.length>1){this.add.apply(this,Array.prototype.slice.call(arguments,1));this.end();}return fs;},container:function(c){var l=new Ext.form.Layout(c);this.start(l);if(arguments.length>1){this.add.apply(this,Array.prototype.slice.call(arguments,1));this.end();}return l;},start:function(c){Ext.applyIf(c,{"labelAlign":this.active.labelAlign,"labelWidth":this.active.labelWidth,"itemCls":this.active.itemCls});this.active.stack.push(c);c.ownerCt=this.active;this.active=c;return this;},end:function(){if(this.active==this.root){return this;}this.active=this.active.ownerCt;return this;},add:function(){this.active.stack.push.apply(this.active.stack,arguments);var r=[];for(var i=0,a=arguments,_c=a.length;i<_c;i++){if(a[i].isFormField){r.push(a[i]);}}if(r.length>0){Ext.form.Form.superclass.add.apply(this,r);}return this;},render:function(ct){ct=Ext.get(ct);var o=this.autoCreate||{tag:"form",method:this.method||"POST",id:this.id||Ext.id()};this.initEl(ct.createChild(o));this.root.render(this.el);this.items.each(function(f){f.render("x-form-el-"+f.id);});if(this.buttons.length>0){var tb=this.el.createChild({cls:"x-form-btns-ct",cn:{cls:"x-form-btns x-form-btns-"+this.buttonAlign,html:"<table cellspacing=\"0\"><tbody><tr></tr></tbody></table><div class=\"x-clear\"></div>"}},null,true);var tr=tb.getElementsByTagName("tr")[0];for(var i=0,len=this.buttons.length;i<len;i++){var b=this.buttons[i];var td=document.createElement("td");td.className="x-form-btn-td";b.render(tr.appendChild(td));}}return this;},addButton:function(_16,_17,_18){var bc={handler:_17,scope:_18,minWidth:this.minButtonWidth,hideParent:true};if(typeof _16=="string"){bc.text=_16;}else{Ext.apply(bc,_16);}var btn=new Ext.Button(null,bc);this.buttons.push(btn);return btn;}});Ext.Form=Ext.form.Form;
+
+Ext.form.Action=function(_1,_2){this.form=_1;this.options=_2||{};};Ext.form.Action.CLIENT_INVALID="client";Ext.form.Action.SERVER_INVALID="server";Ext.form.Action.CONNECT_FAILURE="connect";Ext.form.Action.LOAD_FAILURE="load";Ext.form.Action.prototype={type:"default",failureType:undefined,response:undefined,result:undefined,run:function(_3){},success:function(_4){},handleResponse:function(_5){},failure:function(_6){this.failureType=Ext.form.Action.CONNECT_FAILURE;this.form.afterAction(this,false);},processResponse:function(_7){this.response=_7;if(!_7.responseText){return true;}this.result=this.handleResponse(_7);return this.result;},getUrl:function(_8){var _9=this.options.url||this.form.url||this.form.el.dom.action;if(_8){var p=this.getParams();if(p){_9+=(_9.indexOf("?")!=-1?"&":"?")+p;}}return _9;},getMethod:function(){return (this.options.method||this.form.method||this.form.el.dom.method||"POST").toUpperCase();},getParams:function(){var bp=this.form.baseParams;var p=this.options.params;if(p){if(typeof p=="object"){p=Ext.urlEncode(Ext.applyIf(p,bp));}else{if(typeof p=="string"&&bp){p+="&"+Ext.urlEncode(bp);}}}else{if(bp){p=Ext.urlEncode(bp);}}return p;},createCallback:function(){return {success:this.success,failure:this.failure,scope:this,timeout:(this.form.timeout*1000),upload:this.form.fileUpload?this.success:undefined};}};Ext.form.Action.Submit=function(_d,_e){Ext.form.Action.Submit.superclass.constructor.call(this,_d,_e);};Ext.extend(Ext.form.Action.Submit,Ext.form.Action,{type:"submit",run:function(){var o=this.options;var _10=this.getMethod()=="POST";if(o.clientValidation===false||this.form.isValid()){Ext.lib.Ajax.formRequest(this.form.el.dom,this.getUrl(!_10),this.createCallback(),_10?this.getParams():null,this.form.fileUpload,Ext.SSL_SECURE_URL);}else{if(o.clientValidation!==false){this.failureType=Ext.form.Action.CLIENT_INVALID;this.form.afterAction(this,false);}}},success:function(_11){var _12=this.processResponse(_11);if(_12===true||_12.success){this.form.afterAction(this,true);return;}if(_12.errors){this.form.markInvalid(_12.errors);this.failureType=Ext.form.Action.SERVER_INVALID;this.form.afterAction(this,false);}},handleResponse:function(_13){if(this.form.errorReader){var rs=this.form.errorReader.read(_13);var _15=[];if(rs.records){for(var i=0,len=rs.records.length;i<len;i++){var r=rs.records[i];_15[i]=r.data;}}if(_15.length<1){_15=null;}return {success:rs.success,errors:_15};}return Ext.decode(_13.responseText);}});Ext.form.Action.Load=function(_19,_1a){Ext.form.Action.Load.superclass.constructor.call(this,_19,_1a);this.reader=this.form.reader;};Ext.extend(Ext.form.Action.Load,Ext.form.Action,{type:"load",run:function(){Ext.lib.Ajax.request(this.getMethod(),this.getUrl(false),this.createCallback(),this.getParams());},success:function(_1b){var _1c=this.processResponse(_1b);if(_1c===true||!_1c.success||!_1c.data){this.failureType=Ext.form.Action.LOAD_FAILURE;this.form.afterAction(this,false);return;}this.form.clearInvalid();this.form.setValues(_1c.data);this.form.afterAction(this,true);},handleResponse:function(_1d){if(this.form.reader){var rs=this.form.reader.read(_1d);var _1f=rs.records&&rs.records[0]?rs.records[0].data:null;return {success:rs.success,data:_1f};}return Ext.decode(_1d.responseText);}});Ext.form.Action.ACTION_TYPES={"load":Ext.form.Action.Load,"submit":Ext.form.Action.Submit};
+
+Ext.form.Layout=function(_1){Ext.form.Layout.superclass.constructor.call(this,_1);this.stack=[];};Ext.extend(Ext.form.Layout,Ext.Component,{clear:true,labelSeparator:":",hideLabels:false,defaultAutoCreate:{tag:"div",cls:"x-form-ct"},onRender:function(ct){if(this.el){this.el=Ext.get(this.el);}else{var _3=this.getAutoCreate();this.el=ct.createChild(_3);}if(this.style){this.el.applyStyles(this.style);}if(this.labelAlign){this.el.addClass("x-form-label-"+this.labelAlign);}if(this.hideLabels){this.labelStyle="display:none";this.elementStyle="padding-left:0;";}else{if(typeof this.labelWidth=="number"){this.labelStyle="width:"+this.labelWidth+"px;";this.elementStyle="padding-left:"+((this.labelWidth+(typeof this.labelPad=="number"?this.labelPad:5))+"px")+";";}if(this.labelAlign=="top"){this.labelStyle="width:auto;";this.elementStyle="padding-left:0;";}}var _4=this.stack;var _5=_4.length;if(_5>0){if(!this.fieldTpl){var t=new Ext.Template("<div class=\"x-form-item {5}\">","<label for=\"{0}\" style=\"{2}\">{1}{4}</label>","<div class=\"x-form-element\" id=\"x-form-el-{0}\" style=\"{3}\">","</div>","</div><div class=\"x-form-clear-left\"></div>");t.disableFormats=true;t.compile();Ext.form.Layout.prototype.fieldTpl=t;}for(var i=0;i<_5;i++){if(_4[i].isFormField){this.renderField(_4[i]);}else{this.renderComponent(_4[i]);}}}if(this.clear){this.el.createChild({cls:"x-form-clear"});}},renderField:function(f){this.fieldTpl.append(this.el,[f.id,f.fieldLabel,f.labelStyle||this.labelStyle||"",this.elementStyle||"",f.labelSeparator||this.labelSeparator,f.itemCls||this.itemCls||""]);},renderComponent:function(c){c.render(this.el);}});Ext.form.Column=function(_a){Ext.form.Column.superclass.constructor.call(this,_a);};Ext.extend(Ext.form.Column,Ext.form.Layout,{defaultAutoCreate:{tag:"div",cls:"x-form-ct x-form-column"},onRender:function(ct){Ext.form.Column.superclass.onRender.call(this,ct);if(this.width){this.el.setWidth(this.width);}}});Ext.form.FieldSet=function(_c){Ext.form.FieldSet.superclass.constructor.call(this,_c);};Ext.extend(Ext.form.FieldSet,Ext.form.Layout,{defaultAutoCreate:{tag:"fieldset",cn:{tag:"legend"}},onRender:function(ct){Ext.form.FieldSet.superclass.onRender.call(this,ct);if(this.legend){this.setLegend(this.legend);}},setLegend:function(_e){if(this.rendered){this.el.child("legend").update(_e);}}});
+
+Ext.form.VTypes=function(){var _1=/^[a-zA-Z_]+$/;var _2=/^[a-zA-Z0-9_]+$/;var _3=/^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,4}){1,2}$/;var _4=/(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;return {"email":function(v){return _3.test(v);},"emailText":"This field should be an e-mail address in the format \"user at domain.com\"","emailMask":/[a-z0-9_\.\-@]/i,"url":function(v){return _4.test(v);},"urlText":"This field should be a URL in the format \"http:/"+"/www.domain.com\"","alpha":function(v){return _1.test(v);},"alphaText":"This field should only contain letters and _","alphaMask":/[a-z_]/i,"alphanum":function(v){return _2.test(v);},"alphanumText":"This field should only contain letters, numbers and _","alphanumMask":/[a-z0-9_]/i};}();
+
+Ext.LayoutManager=function(_1){Ext.LayoutManager.superclass.constructor.call(this);this.el=Ext.get(_1);if(this.el.dom==document.body&&Ext.isIE){document.body.scroll="no";}else{if(this.el.dom!=document.body&&this.el.getStyle("position")=="static"){this.el.position("relative");}}this.id=this.el.id;this.el.addClass("x-layout-container");this.monitorWindowResize=true;this.regions={};this.events={"layout":true,"regionresized":true,"regioncollapsed":true,"regionexpanded":true};this.updating=false;Ext.EventManager.onWindowResize(this.onWindowResize,this,true);};Ext.extend(Ext.LayoutManager,Ext.util.Observable,{isUpdating:function(){return this.updating;},beginUpdate:function(){this.updating=true;},endUpdate:function(_2){this.updating=false;if(!_2){this.layout();}},layout:function(){},onRegionResized:function(_3,_4){this.fireEvent("regionresized",_3,_4);this.layout();},onRegionCollapsed:function(_5){this.fireEvent("regioncollapsed",_5);},onRegionExpanded:function(_6){this.fireEvent("regionexpanded",_6);},getViewSize:function(){var _7;if(this.el.dom!=document.body){_7=this.el.getSize();}else{_7={width:Ext.lib.Dom.getViewWidth(),height:Ext.lib.Dom.getViewHeight()};}_7.width-=this.el.getBorderWidth("lr")-this.el.getPadding("lr");_7.height-=this.el.getBorderWidth("tb")-this.el.getPadding("tb");return _7;},getEl:function(){return this.el;},getRegion:function(_8){return this.regions[_8.toLowerCase()];},onWindowResize:function(){if(this.monitorWindowResize){this.layout();}}});
+
+Ext.BorderLayout=function(_1,_2){_2=_2||{};Ext.BorderLayout.superclass.constructor.call(this,_1);this.factory=_2.factory||Ext.BorderLayout.RegionFactory;for(var i=0,_4=this.factory.validRegions.length;i<_4;i++){var _5=this.factory.validRegions[i];if(_2[_5]){this.addRegion(_5,_2[_5]);}}};Ext.extend(Ext.BorderLayout,Ext.LayoutManager,{addRegion:function(_6,_7){if(!this.regions[_6]){var r=this.factory.create(_6,this,_7);this.regions[_6]=r;r.on("visibilitychange",this.layout,this);r.on("paneladded",this.layout,this);r.on("panelremoved",this.layout,this);r.on("invalidated",this.layout,this);r.on("resized",this.onRegionResized,this);r.on("collapsed",this.onRegionCollapsed,this);r.on("expanded",this.onRegionExpanded,this);}return this.regions[_6];},layout:function(){if(this.updating){return;}var _9=this.getViewSize();var w=_9.width,h=_9.height;var _c=w,_d=h,_e=0,_f=0;var rs=this.regions;var n=rs["north"],s=rs["south"],_13=rs["west"],e=rs["east"],c=rs["center"];if(this.hideOnLayout){c.el.setStyle("display","none");}if(n&&n.isVisible()){var b=n.getBox();var m=n.getMargins();b.width=w-(m.left+m.right);b.x=m.left;b.y=m.top;_e=b.height+b.y+m.bottom;_d-=_e;n.updateBox(this.safeBox(b));}if(s&&s.isVisible()){var b=s.getBox();var m=s.getMargins();b.width=w-(m.left+m.right);b.x=m.left;var _18=(b.height+m.top+m.bottom);b.y=h-_18+m.top;_d-=_18;s.updateBox(this.safeBox(b));}if(_13&&_13.isVisible()){var b=_13.getBox();var m=_13.getMargins();b.height=_d-(m.top+m.bottom);b.x=m.left;b.y=_e+m.top;var _19=(b.width+m.left+m.right);_f+=_19;_c-=_19;_13.updateBox(this.safeBox(b));}if(e&&e.isVisible()){var b=e.getBox();var m=e.getMargins();b.height=_d-(m.top+m.bottom);var _19=(b.width+m.left+m.right);b.x=w-_19+m.left;b.y=_e+m.top;_c-=_19;e.updateBox(this.safeBox(b));}if(c){var m=c.getMargins();var _1a={x:_f+m.left,y:_e+m.top,width:_c-(m.left+m.right),height:_d-(m.top+m.bottom)};if(this.hideOnLayout){c.el.setStyle("display","block");}c.updateBox(this.safeBox(_1a));}this.el.repaint();this.fireEvent("layout",this);},safeBox:function(box){box.width=Math.max(0,box.width);box.height=Math.max(0,box.height);return box;},add:function(_1c,_1d){_1c=_1c.toLowerCase();return this.regions[_1c].add(_1d);},remove:function(_1e,_1f){_1e=_1e.toLowerCase();return this.regions[_1e].remove(_1f);},findPanel:function(_20){var rs=this.regions;for(var _22 in rs){if(typeof rs[_22]!="function"){var p=rs[_22].getPanel(_20);if(p){return p;}}}return null;},showPanel:function(_24){var rs=this.regions;for(var _26 in rs){var r=rs[_26];if(typeof r!="function"){if(r.hasPanel(_24)){return r.showPanel(_24);}}}return null;},restoreState:function(_28){if(!_28){_28=Ext.state.Manager;}var sm=new Ext.LayoutStateManager();sm.init(this,_28);},batchAdd:function(_2a){this.beginUpdate();for(var _2b in _2a){var lr=this.regions[_2b];if(lr){this.addTypedPanels(lr,_2a[_2b]);}}this.endUpdate();},addTypedPanels:function(lr,ps){if(typeof ps=="string"){lr.add(new Ext.ContentPanel(ps));}else{if(ps instanceof Array){for(var i=0,len=ps.length;i<len;i++){this.addTypedPanels(lr,ps[i]);}}else{if(!ps.events){var el=ps.el;delete ps.el;lr.add(new Ext.ContentPanel(el||Ext.id(),ps));}else{lr.add(ps);}}}}});Ext.BorderLayout.create=function(_32,_33){var _34=new Ext.BorderLayout(_33||document.body,_32);_34.beginUpdate();var _35=Ext.BorderLayout.RegionFactory.validRegions;for(var j=0,_37=_35.length;j<_37;j++){var lr=_35[j];if(_34.regions[lr]&&_32[lr].panels){var r=_34.regions[lr];var ps=_32[lr].panels;_34.addTypedPanels(r,ps);}}_34.endUpdate();return _34;};Ext.BorderLayout.RegionFactory={validRegions:["north","south","east","west","center"],create:function(_3b,mgr,_3d){_3b=_3b.toLowerCase();if(_3d.lightweight||_3d.basic){return new Ext.BasicLayoutRegion(mgr,_3d,_3b);}switch(_3b){case "north":return new Ext.NorthLayoutRegion(mgr,_3d);case "south":return new Ext.SouthLayoutRegion(mgr,_3d);case "east":return new Ext.EastLayoutRegion(mgr,_3d);case "west":return new Ext.WestLayoutRegion(mgr,_3d);case "center":return new Ext.CenterLayoutRegion(mgr,_3d);}throw "Layout region \""+_3b+"\" not supported.";}};
+
+Ext.BasicLayoutRegion=function(_1,_2,_3,_4){this.mgr=_1;this.position=_3;this.events={"beforeremove":true,"invalidated":true,"visibilitychange":true,"paneladded":true,"panelremoved":true,"collapsed":true,"expanded":true,"slideshow":true,"slidehide":true,"panelactivated":true,"resized":true};this.panels=new Ext.util.MixedCollection();this.panels.getKey=this.getPanelId.createDelegate(this);this.box=null;this.activePanel=null;if(_4!==true){this.applyConfig(_2);}};Ext.extend(Ext.BasicLayoutRegion,Ext.util.Observable,{getPanelId:function(p){return p.getId();},applyConfig:function(_6){this.margins=_6.margins||this.margins||{top:0,left:0,right:0,bottom:0};this.config=_6;},resizeTo:function(_7){var el=this.el?this.el:(this.activePanel?this.activePanel.getEl():null);if(el){switch(this.position){case "east":case "west":el.setWidth(_7);this.fireEvent("resized",this,_7);break;case "north":case "south":el.setHeight(_7);this.fireEvent("resized",this,_7);break;}}},getBox:function(){return this.activePanel?this.activePanel.getEl().getBox(false,true):null;},getMargins:function(){return this.margins;},updateBox:function(_9){this.box=_9;var el=this.activePanel.getEl();el.dom.style.left=_9.x+"px";el.dom.style.top=_9.y+"px";el.setSize(_9.width,_9.height);},getEl:function(){return this.activePanel;},isVisible:function(){return this.activePanel?true:false;},setActivePanel:function(_b){_b=this.getPanel(_b);if(this.activePanel&&this.activePanel!=_b){this.activePanel.setActiveState(false);this.activePanel.getEl().setStyle({left:-10000,right:-10000});}this.activePanel=_b;_b.setActiveState(true);if(this.box){_b.setSize(this.box.width,this.box.height);}this.fireEvent("panelactivated",this,_b);this.fireEvent("invalidated");},showPanel:function(_c){if(_c=this.getPanel(_c)){this.setActivePanel(_c);}return _c;},getActivePanel:function(){return this.activePanel;},add:function(_d){if(arguments.length>1){for(var i=0,_f=arguments.length;i<_f;i++){this.add(arguments[i]);}return null;}if(this.hasPanel(_d)){this.showPanel(_d);return _d;}var el=_d.getEl();if(el.dom.parentNode!=this.mgr.el.dom){this.mgr.el.dom.appendChild(el.dom);}_d.setRegion(this);this.panels.add(_d);el.setStyle("position","absolute");if(!_d.background){this.setActivePanel(_d);if(this.config.initialSize&&this.panels.getCount()==1){this.resizeTo(this.config.initialSize);}}this.fireEvent("paneladded",this,_d);return _d;},hasPanel:function(_11){if(typeof _11=="object"){_11=_11.getId();}return this.getPanel(_11)?true:false;},remove:function(_12,_13){_12=this.getPanel(_12);if(!_12){return null;}var e={};this.fireEvent("beforeremove",this,_12,e);if(e.cancel===true){return null;}var _15=_12.getId();this.panels.removeKey(_15);return _12;},getPanel:function(id){if(typeof id=="object"){return id;}return this.panels.get(id);},getPosition:function(){return this.position;}});
+
+Ext.LayoutRegion=function(_1,_2,_3){Ext.LayoutRegion.superclass.constructor.call(this,_1,_2,_3,true);var dh=Ext.DomHelper;this.el=dh.append(_1.el.dom,{tag:"div",cls:"x-layout-panel x-layout-panel-"+this.position},true);this.titleEl=dh.append(this.el.dom,{tag:"div",unselectable:"on",cls:"x-unselectable x-layout-panel-hd x-layout-title-"+this.position,children:[{tag:"span",cls:"x-unselectable x-layout-panel-hd-text",unselectable:"on",html:"&#160;"},{tag:"div",cls:"x-unselectable x-layout-panel-hd-tools",unselectable:"on"}]},true);this.titleEl.enableDisplayMode();this.titleTextEl=this.titleEl.dom.firstChild;this.tools=Ext.get(this.titleEl.dom.childNodes[1],true);this.closeBtn=this.createTool(this.tools.dom,"x-layout-close");this.closeBtn.enableDisplayMode();this.closeBtn.on("click",this.closeClicked,this);this.closeBtn.hide();this.bodyEl=dh.append(this.el.dom,{tag:"div",cls:"x-layout-panel-body"},true);this.visible=true;this.collapsed=false;if(_2.hideWhenEmpty){this.hide();this.on("paneladded",this.validateVisibility,this);this.on("panelremoved",this.validateVisibility,this);}this.applyConfig(_2);};Ext.extend(Ext.LayoutRegion,Ext.BasicLayoutRegion,{applyConfig:function(c){if(c.collapsible&&this.position!="center"&&!this.collapsedEl){var dh=Ext.DomHelper;this.collapseBtn=this.createTool(this.tools.dom,"x-layout-collapse-"+this.position);this.collapseBtn.on("click",this.collapse,this);this.collapseBtn.enableDisplayMode();this.collapsedEl=dh.append(this.mgr.el.dom,{cls:"x-layout-collapsed x-layout-collapsed-"+this.position,children:[{cls:"x-layout-collapsed-tools",children:[{cls:"x-layout-ctools-inner"}]}]},true);if(c.floatable!==false){this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this.collapseClick,this);}if(c.showPin===true||this.showPin==true){this.stickBtn=this.createTool(this.tools.dom,"x-layout-stick");this.stickBtn.enableDisplayMode();this.stickBtn.on("click",this.expand,this);this.stickBtn.hide();}if(c.collapsedTitle&&(this.position=="north"||this.position=="south")){this.collapsedTitleTextEl=dh.append(this.collapsedEl.dom,{tag:"div",cls:"x-unselectable x-layout-panel-hd-text",id:"message",unselectable:"on",style:{"float":"left"}});this.collapsedTitleTextEl.innerHTML=c.collapsedTitle;}this.expandBtn=this.createTool(this.collapsedEl.dom.firstChild.firstChild,"x-layout-expand-"+this.position);this.expandBtn.on("click",this.expand,this);}if(this.collapseBtn){this.collapseBtn.setVisible(c.collapsible==true);}this.cmargins=c.cmargins||this.cmargins||(this.position=="west"||this.position=="east"?{top:0,left:2,right:2,bottom:0}:{top:2,left:0,right:0,bottom:2});this.margins=c.margins||this.margins||{top:0,left:0,right:0,bottom:0};this.bottomTabs=c.tabPosition!="top";this.autoScroll=c.autoScroll||false;if(this.autoScroll){this.bodyEl.setStyle("overflow","auto");}else{this.bodyEl.setStyle("overflow","hidden");}if((!c.titlebar&&!c.title)||c.titlebar===false){this.titleEl.hide();}else{this.titleEl.show();if(c.title){this.titleTextEl.innerHTML=c.title;}}this.duration=c.duration||0.3;this.slideDuration=c.slideDuration||0.45;this.config=c;if(c.collapsed){this.collapse(true);}if(c.hidden){this.hide();}},isVisible:function(){return this.visible;},setCollapsedTitle:function(_7){_7=_7||"&#160;";if(this.collapsedTitleTextEl){this.collapsedTitleTextEl.innerHTML=_7;}},getBox:function(){var b;if(!this.collapsed){b=this.el.getBox(false,true);}else{b=this.collapsedEl.getBox(false,true);}return b;},getMargins:function(){return this.collapsed?this.cmargins:this.margins;},highlight:function(){this.el.addClass("x-layout-panel-dragover");},unhighlight:function(){this.el.removeClass("x-layout-panel-dragover");},updateBox:function(_9){this.box=_9;if(!this.collapsed){this.el.dom.style.left=_9.x+"px";this.el.dom.style.top=_9.y+"px";this.updateBody(_9.width,_9.height);}else{this.collapsedEl.dom.style.left=_9.x+"px";this.collapsedEl.dom.style.top=_9.y+"px";this.collapsedEl.setSize(_9.width,_9.height);}if(this.tabs){this.tabs.autoSizeTabs();}},updateBody:function(w,h){if(w!==null){this.el.setWidth(w);w-=this.el.getBorderWidth("rl");}if(h!==null){this.el.setHeight(h);h=this.titleEl.isDisplayed()?h-(this.titleEl.getHeight()||0):h;h-=this.el.getBorderWidth("tb");this.bodyEl.setHeight(h);if(this.tabs){h=this.tabs.syncHeight(h);}}if(this.panelSize){w=w!==null?w:this.panelSize.width;h=h!==null?h:this.panelSize.height;}if(this.activePanel){var el=this.activePanel.getEl();w=w!==null?w:el.getWidth();h=h!==null?h:el.getHeight();this.panelSize={width:w,height:h};this.activePanel.setSize(w,h);}if(Ext.isIE&&this.tabs){this.tabs.el.repaint();}},getEl:function(){return this.el;},hide:function(){if(!this.collapsed){this.el.dom.style.left="-2000px";this.el.hide();}else{this.collapsedEl.dom.style.left="-2000px";this.collapsedEl.hide();}this.visible=false;this.fireEvent("visibilitychange",this,false);},show:function(){if(!this.collapsed){this.el.show();}else{this.collapsedEl.show();}this.visible=true;this.fireEvent("visibilitychange",this,true);},closeClicked:function(){if(this.activePanel){this.remove(this.activePanel);}},collapseClick:function(e){if(this.isSlid){e.stopPropagation();this.slideIn();}else{e.stopPropagation();this.slideOut();}},collapse:function(_e){if(this.collapsed){return;}this.collapsed=true;if(this.split){this.split.el.hide();}if(this.config.animate&&_e!==true){this.fireEvent("invalidated",this);this.animateCollapse();}else{this.el.setLocation(-20000,-20000);this.el.hide();this.collapsedEl.show();this.fireEvent("collapsed",this);this.fireEvent("invalidated",this);}},animateCollapse:function(){},expand:function(e,_10){if(e){e.stopPropagation();}if(!this.collapsed||this.el.hasActiveFx()){return;}if(this.isSlid){this.afterSlideIn();_10=true;}this.collapsed=false;if(this.config.animate&&_10!==true){this.animateExpand();}else{this.el.show();if(this.split){this.split.el.show();}this.collapsedEl.setLocation(-2000,-2000);this.collapsedEl.hide();this.fireEvent("invalidated",this);this.fireEvent("expanded",this);}},animateExpand:function(){},initTabs:function(){this.bodyEl.setStyle("overflow","hidden");var ts=new Ext.TabPanel(this.bodyEl.dom,{tabPosition:this.bottomTabs?"bottom":"top",disableTooltips:this.config.disableTabTips});if(this.config.hideTabs){ts.stripWrap.setDisplayed(false);}this.tabs=ts;ts.resizeTabs=this.config.resizeTabs===true;ts.minTabWidth=this.config.minTabWidth||40;ts.maxTabWidth=this.config.maxTabWidth||250;ts.preferredTabWidth=this.config.preferredTabWidth||150;ts.monitorResize=false;ts.bodyEl.setStyle("overflow",this.config.autoScroll?"auto":"hidden");ts.bodyEl.addClass("x-layout-tabs-body");this.panels.each(this.initPanelAsTab,this);},initPanelAsTab:function(_12){var ti=this.tabs.addTab(_12.getEl().id,_12.getTitle(),null,this.config.closeOnTab&&_12.isClosable());if(_12.tabTip!==undefined){ti.setTooltip(_12.tabTip);}ti.on("activate",function(){this.setActivePanel(_12);},this);if(this.config.closeOnTab){ti.on("beforeclose",function(t,e){e.cancel=true;this.remove(_12);},this);}return ti;},updatePanelTitle:function(_16,_17){if(this.activePanel==_16){this.updateTitle(_17);}if(this.tabs){var ti=this.tabs.getTab(_16.getEl().id);ti.setText(_17);if(_16.tabTip!==undefined){ti.setTooltip(_16.tabTip);}}},updateTitle:function(_19){if(this.titleTextEl&&!this.config.title){this.titleTextEl.innerHTML=(typeof _19!="undefined"&&_19.length>0?_19:"&#160;");}},setActivePanel:function(_1a){_1a=this.getPanel(_1a);if(this.activePanel&&this.activePanel!=_1a){this.activePanel.setActiveState(false);}this.activePanel=_1a;_1a.setActiveState(true);if(this.panelSize){_1a.setSize(this.panelSize.width,this.panelSize.height);}this.closeBtn.setVisible(!this.config.closeOnTab&&!this.isSlid&&_1a.isClosable());this.updateTitle(_1a.getTitle());if(this.tabs){this.fireEvent("invalidated",this);}this.fireEvent("panelactivated",this,_1a);},showPanel:function(_1b){if(_1b=this.getPanel(_1b)){if(this.tabs){var tab=this.tabs.getTab(_1b.getEl().id);if(tab.isHidden()){this.tabs.unhideTab(tab.id);}tab.activate();}else{this.setActivePanel(_1b);}}return _1b;},getActivePanel:function(){return this.activePanel;},validateVisibility:function(){if(this.panels.getCount()<1){this.updateTitle("&#160;");this.closeBtn.hide();this.hide();}else{if(!this.isVisible()){this.show();}}},add:function(_1d){if(arguments.length>1){for(var i=0,len=arguments.length;i<len;i++){this.add(arguments[i]);}return null;}if(this.hasPanel(_1d)){this.showPanel(_1d);return _1d;}_1d.setRegion(this);this.panels.add(_1d);if(this.panels.getCount()==1&&!this.config.alwaysShowTabs){this.bodyEl.dom.appendChild(_1d.getEl().dom);if(_1d.background!==true){this.setActivePanel(_1d);}this.fireEvent("paneladded",this,_1d);return _1d;}if(!this.tabs){this.initTabs();}else{this.initPanelAsTab(_1d);}if(_1d.background!==true){this.tabs.activate(_1d.getEl().id);}this.fireEvent("paneladded",this,_1d);return _1d;},hidePanel:function(_20){if(this.tabs&&(_20=this.getPanel(_20))){this.tabs.hideTab(_20.getEl().id);}},unhidePanel:function(_21){if(this.tabs&&(_21=this.getPanel(_21))){this.tabs.unhideTab(_21.getEl().id);}},clearPanels:function(){while(this.panels.getCount()>0){this.remove(this.panels.first());}},remove:function(_22,_23){_22=this.getPanel(_22);if(!_22){return null;}var e={};this.fireEvent("beforeremove",this,_22,e);if(e.cancel===true){return null;}_23=(typeof _23!="undefined"?_23:(this.config.preservePanels===true||_22.preserve===true));var _25=_22.getId();this.panels.removeKey(_25);if(_23){document.body.appendChild(_22.getEl().dom);}if(this.tabs){this.tabs.removeTab(_22.getEl().id);}else{if(!_23){this.bodyEl.dom.removeChild(_22.getEl().dom);}}if(this.panels.getCount()==1&&this.tabs&&!this.config.alwaysShowTabs){var p=this.panels.first();var _27=document.createElement("div");_27.appendChild(p.getEl().dom);this.bodyEl.update("");this.bodyEl.dom.appendChild(p.getEl().dom);_27=null;this.updateTitle(p.getTitle());this.tabs=null;this.bodyEl.setStyle("overflow",this.config.autoScroll?"auto":"hidden");this.setActivePanel(p);}_22.setRegion(null);if(this.activePanel==_22){this.activePanel=null;}if(this.config.autoDestroy!==false&&_23!==true){try{_22.destroy();}catch(e){}}this.fireEvent("panelremoved",this,_22);return _22;},getTabs:function(){return this.tabs;},createTool:function(_28,_29){var btn=Ext.DomHelper.append(_28,{tag:"div",cls:"x-layout-tools-button",children:[{tag:"div",cls:"x-layout-tools-button-inner "+_29,html:"&#160;"}]},true);btn.addClassOnOver("x-layout-tools-button-over");return btn;}});
+
+Ext.SplitLayoutRegion=function(_1,_2,_3,_4){this.cursor=_4;Ext.SplitLayoutRegion.superclass.constructor.call(this,_1,_2,_3);};Ext.extend(Ext.SplitLayoutRegion,Ext.LayoutRegion,{splitTip:"Drag to resize.",collapsibleSplitTip:"Drag to resize. Double click to hide.",useSplitTips:false,applyConfig:function(_5){Ext.SplitLayoutRegion.superclass.applyConfig.call(this,_5);if(_5.split){if(!this.split){var _6=Ext.DomHelper.append(this.mgr.el.dom,{tag:"div",id:this.el.id+"-split",cls:"x-layout-split x-layout-split-"+this.position,html:"&#160;"});this.split=new Ext.SplitBar(_6,this.el,this.orientation);this.split.on("moved",this.onSplitMove,this);this.split.useShim=_5.useShim===true;this.split.getMaximumSize=this[this.position=="north"||this.position=="south"?"getVMaxSize":"getHMaxSize"].createDelegate(this);if(this.useSplitTips){this.split.el.dom.title=_5.collapsible?this.collapsibleSplitTip:this.splitTip;}if(_5.collapsible){this.split.el.on("dblclick",this.collapse,this);}}if(typeof _5.minSize!="undefined"){this.split.minSize=_5.minSize;}if(typeof _5.maxSize!="undefined"){this.split.maxSize=_5.maxSize;}if(_5.hideWhenEmpty||_5.hidden){this.hideSplitter();}}},getHMaxSize:function(){var _7=this.config.maxSize||10000;var _8=this.mgr.getRegion("center");return Math.min(_7,(this.el.getWidth()+_8.getEl().getWidth())-_8.getMinWidth());},getVMaxSize:function(){var _9=this.config.maxSize||10000;var _a=this.mgr.getRegion("center");return Math.min(_9,(this.el.getHeight()+_a.getEl().getHeight())-_a.getMinHeight());},onSplitMove:function(_b,_c){this.fireEvent("resized",this,_c);},getSplitBar:function(){return this.split;},hide:function(){this.hideSplitter();Ext.SplitLayoutRegion.superclass.hide.call(this);},hideSplitter:function(){if(this.split){this.split.el.setLocation(-2000,-2000);this.split.el.hide();}},show:function(){if(this.split){this.split.el.show();}Ext.SplitLayoutRegion.superclass.show.call(this);},beforeSlide:function(){if(Ext.isGecko){this.bodyEl.clip();if(this.tabs){this.tabs.bodyEl.clip();}if(this.activePanel){this.activePanel.getEl().clip();if(this.activePanel.beforeSlide){this.activePanel.beforeSlide();}}}},afterSlide:function(){if(Ext.isGecko){this.bodyEl.unclip();if(this.tabs){this.tabs.bodyEl.unclip();}if(this.activePanel){this.activePanel.getEl().unclip();if(this.activePanel.afterSlide){this.activePanel.afterSlide();}}}},initAutoHide:function(){if(this.autoHide!==false){if(!this.autoHideHd){var st=new Ext.util.DelayedTask(this.slideIn,this);this.autoHideHd={"mouseout":function(e){if(!e.within(this.el,true)){st.delay(500);}},"mouseover":function(e){st.cancel();},scope:this};}this.el.on(this.autoHideHd);}},clearAutoHide:function(){if(this.autoHide!==false){this.el.un("mouseout",this.autoHideHd.mouseout);this.el.un("mouseover",this.autoHideHd.mouseover);}},clearMonitor:function(){Ext.get(document).un("click",this.slideInIf,this);},slideOut:function(){if(this.isSlid||this.el.hasActiveFx()){return;}this.isSlid=true;if(this.collapseBtn){this.collapseBtn.hide();}this.closeBtnState=this.closeBtn.getStyle("display");this.closeBtn.hide();if(this.stickBtn){this.stickBtn.show();}this.el.show();this.el.alignTo(this.collapsedEl,this.getCollapseAnchor());this.beforeSlide();this.el.setStyle("z-index",20000);this.el.slideIn(this.getSlideAnchor(),{callback:function(){this.afterSlide();this.initAutoHide();Ext.get(document).on("click",this.slideInIf,this);this.fireEvent("slideshow",this);},scope:this,block:true});},afterSlideIn:function(){this.clearAutoHide();this.isSlid=false;this.clearMonitor();this.el.setStyle("z-index","");if(this.collapseBtn){this.collapseBtn.show();}this.closeBtn.setStyle("display",this.closeBtnState);if(this.stickBtn){this.stickBtn.hide();}this.fireEvent("slidehide",this);},slideIn:function(cb){if(!this.isSlid||this.el.hasActiveFx()){Ext.callback(cb);return;}this.isSlid=false;this.beforeSlide();this.el.slideOut(this.getSlideAnchor(),{callback:function(){this.el.setLeftTop(-10000,-10000);this.afterSlide();this.afterSlideIn();Ext.callback(cb);},scope:this,block:true});},slideInIf:function(e){if(!e.within(this.el)){this.slideIn();}},animateCollapse:function(){this.beforeSlide();this.el.setStyle("z-index",20000);var _12=this.getSlideAnchor();this.el.slideOut(_12,{callback:function(){this.el.setStyle("z-index","");this.collapsedEl.slideIn(_12,{duration:0.3});this.afterSlide();this.el.setLocation(-10000,-10000);this.el.hide();this.fireEvent("collapsed",this);},scope:this,block:true});},animateExpand:function(){this.beforeSlide();this.el.alignTo(this.collapsedEl,this.getCollapseAnchor(),this.getExpandAdj());this.el.setStyle("z-index",20000);this.collapsedEl.hide({duration:0.1});this.el.slideIn(this.getSlideAnchor(),{callback:function(){this.el.setStyle("z-index","");this.afterSlide();if(this.split){this.split.el.show();}this.fireEvent("invalidated",this);this.fireEvent("expanded",this);},scope:this,block:true});},anchors:{"west":"left","east":"right","north":"top","south":"bottom"},sanchors:{"west":"l","east":"r","north":"t","south":"b"},canchors:{"west":"tl-tr","east":"tr-tl","north":"tl-bl","south":"bl-tl"},getAnchor:function(){return this.anchors[this.position];},getCollapseAnchor:function(){return this.canchors[this.position];},getSlideAnchor:function(){return this.sanchors[this.position];},getAlignAdj:function(){var cm=this.cmargins;switch(this.position){case "west":return [0,0];break;case "east":return [0,0];break;case "north":return [0,0];break;case "south":return [0,0];break;}},getExpandAdj:function(){var c=this.collapsedEl,cm=this.cmargins;switch(this.position){case "west":return [-(cm.right+c.getWidth()+cm.left),0];break;case "east":return [cm.right+c.getWidth()+cm.left,0];break;case "north":return [0,-(cm.top+cm.bottom+c.getHeight())];break;case "south":return [0,cm.top+cm.bottom+c.getHeight()];break;}}});
+
+Ext.CenterLayoutRegion=function(_1,_2){Ext.CenterLayoutRegion.superclass.constructor.call(this,_1,_2,"center");this.visible=true;this.minWidth=_2.minWidth||20;this.minHeight=_2.minHeight||20;};Ext.extend(Ext.CenterLayoutRegion,Ext.LayoutRegion,{hide:function(){},show:function(){},getMinWidth:function(){return this.minWidth;},getMinHeight:function(){return this.minHeight;}});Ext.NorthLayoutRegion=function(_3,_4){Ext.NorthLayoutRegion.superclass.constructor.call(this,_3,_4,"north","n-resize");if(this.split){this.split.placement=Ext.SplitBar.TOP;this.split.orientation=Ext.SplitBar.VERTICAL;this.split.el.addClass("x-layout-split-v");}var _5=_4.initialSize||_4.height;if(typeof _5!="undefined"){this.el.setHeight(_5);}};Ext.extend(Ext.NorthLayoutRegion,Ext.SplitLayoutRegion,{orientation:Ext.SplitBar.VERTICAL,getBox:function(){if(this.collapsed){return this.collapsedEl.getBox();}var _6=this.el.getBox();if(this.split){_6.height+=this.split.el.getHeight();}return _6;},updateBox:function(_7){if(this.split&&!this.collapsed){_7.height-=this.split.el.getHeight();this.split.el.setLeft(_7.x);this.split.el.setTop(_7.y+_7.height);this.split.el.setWidth(_7.width);}if(this.collapsed){this.updateBody(_7.width,null);}Ext.NorthLayoutRegion.superclass.updateBox.call(this,_7);}});Ext.SouthLayoutRegion=function(_8,_9){Ext.SouthLayoutRegion.superclass.constructor.call(this,_8,_9,"south","s-resize");if(this.split){this.split.placement=Ext.SplitBar.BOTTOM;this.split.orientation=Ext.SplitBar.VERTICAL;this.split.el.addClass("x-layout-split-v");}var _a=_9.initialSize||_9.height;if(typeof _a!="undefined"){this.el.setHeight(_a);}};Ext.extend(Ext.SouthLayoutRegion,Ext.SplitLayoutRegion,{orientation:Ext.SplitBar.VERTICAL,getBox:function(){if(this.collapsed){return this.collapsedEl.getBox();}var _b=this.el.getBox();if(this.split){var sh=this.split.el.getHeight();_b.height+=sh;_b.y-=sh;}return _b;},updateBox:function(_d){if(this.split&&!this.collapsed){var sh=this.split.el.getHeight();_d.height-=sh;_d.y+=sh;this.split.el.setLeft(_d.x);this.split.el.setTop(_d.y-sh);this.split.el.setWidth(_d.width);}if(this.collapsed){this.updateBody(_d.width,null);}Ext.SouthLayoutRegion.superclass.updateBox.call(this,_d);}});Ext.EastLayoutRegion=function(_f,_10){Ext.EastLayoutRegion.superclass.constructor.call(this,_f,_10,"east","e-resize");if(this.split){this.split.placement=Ext.SplitBar.RIGHT;this.split.orientation=Ext.SplitBar.HORIZONTAL;this.split.el.addClass("x-layout-split-h");}var _11=_10.initialSize||_10.width;if(typeof _11!="undefined"){this.el.setWidth(_11);}};Ext.extend(Ext.EastLayoutRegion,Ext.SplitLayoutRegion,{orientation:Ext.SplitBar.HORIZONTAL,getBox:function(){if(this.collapsed){return this.collapsedEl.getBox();}var box=this.el.getBox();if(this.split){var sw=this.split.el.getWidth();box.width+=sw;box.x-=sw;}return box;},updateBox:function(box){if(this.split&&!this.collapsed){var sw=this.split.el.getWidth();box.width-=sw;this.split.el.setLeft(box.x);this.split.el.setTop(box.y);this.split.el.setHeight(box.height);box.x+=sw;}if(this.collapsed){this.updateBody(null,box.height);}Ext.EastLayoutRegion.superclass.updateBox.call(this,box);}});Ext.WestLayoutRegion=function(mgr,_17){Ext.WestLayoutRegion.superclass.constructor.call(this,mgr,_17,"west","w-resize");if(this.split){this.split.placement=Ext.SplitBar.LEFT;this.split.orientation=Ext.SplitBar.HORIZONTAL;this.split.el.addClass("x-layout-split-h");}var _18=_17.initialSize||_17.width;if(typeof _18!="undefined"){this.el.setWidth(_18);}};Ext.extend(Ext.WestLayoutRegion,Ext.SplitLayoutRegion,{orientation:Ext.SplitBar.HORIZONTAL,getBox:function(){if(this.collapsed){return this.collapsedEl.getBox();}var box=this.el.getBox();if(this.split){box.width+=this.split.el.getWidth();}return box;},updateBox:function(box){if(this.split&&!this.collapsed){var sw=this.split.el.getWidth();box.width-=sw;this.split.el.setLeft(box.x+box.width);this.split.el.setTop(box.y);this.split.el.setHeight(box.height);}if(this.collapsed){this.updateBody(null,box.height);}Ext.WestLayoutRegion.superclass.updateBox.call(this,box);}});
+
+Ext.LayoutStateManager=function(_1){this.state={north:{},south:{},east:{},west:{}};};Ext.LayoutStateManager.prototype={init:function(_2,_3){this.provider=_3;var _4=_3.get(_2.id+"-layout-state");if(_4){var _5=_2.isUpdating();if(!_5){_2.beginUpdate();}for(var _6 in _4){if(typeof _4[_6]!="function"){var _7=_4[_6];var r=_2.getRegion(_6);if(r&&_7){if(_7.size){r.resizeTo(_7.size);}if(_7.collapsed==true){r.collapse(true);}else{r.expand(null,true);}}}}if(!_5){_2.endUpdate();}this.state=_4;}this.layout=_2;_2.on("regionresized",this.onRegionResized,this);_2.on("regioncollapsed",this.onRegionCollapsed,this);_2.on("regionexpanded",this.onRegionExpanded,this);},storeState:function(){this.provider.set(this.layout.id+"-layout-state",this.state);},onRegionResized:function(_9,_a){this.state[_9.getPosition()].size=_a;this.storeState();},onRegionCollapsed:function(_b){this.state[_b.getPosition()].collapsed=true;this.storeState();},onRegionExpanded:function(_c){this.state[_c.getPosition()].collapsed=false;this.storeState();}};
+
+Ext.ContentPanel=function(el,_2,_3){Ext.ContentPanel.superclass.constructor.call(this);if(el.autoCreate){_2=el;el=Ext.id();}this.el=Ext.get(el);if(!this.el&&_2&&_2.autoCreate){if(typeof _2.autoCreate=="object"){if(!_2.autoCreate.id){_2.autoCreate.id=_2.id||el;}this.el=Ext.DomHelper.append(document.body,_2.autoCreate,true);}else{this.el=Ext.DomHelper.append(document.body,{tag:"div",cls:"x-layout-inactive-content",id:_2.id||el},true);}}this.closable=false;this.loaded=false;this.active=false;if(typeof _2=="string"){this.title=_2;}else{Ext.apply(this,_2);}if(this.resizeEl){this.resizeEl=Ext.get(this.resizeEl,true);}else{this.resizeEl=this.el;}this.events={"activate":true,"deactivate":true,"resize":true};if(this.autoScroll){this.resizeEl.setStyle("overflow","auto");}_3=_3||this.content;if(_3){this.setContent(_3);}if(_2&&_2.url){this.setUrl(this.url,this.params,this.loadOnce);}};Ext.extend(Ext.ContentPanel,Ext.util.Observable,{tabTip:"",setRegion:function(_4){this.region=_4;if(_4){this.el.replaceClass("x-layout-inactive-content","x-layout-active-content");}else{this.el.replaceClass("x-layout-active-content","x-layout-inactive-content");}},getToolbar:function(){return this.toolbar;},setActiveState:function(_5){this.active=_5;if(!_5){this.fireEvent("deactivate",this);}else{this.fireEvent("activate",this);}},setContent:function(_6,_7){this.el.update(_6,_7);},ignoreResize:function(w,h){if(this.lastSize&&this.lastSize.width==w&&this.lastSize.height==h){return true;}else{this.lastSize={width:w,height:h};return false;}},getUpdateManager:function(){return this.el.getUpdateManager();},load:function(){var um=this.el.getUpdateManager();um.update.apply(um,arguments);return this;},setUrl:function(_b,_c,_d){if(this.refreshDelegate){this.removeListener("activate",this.refreshDelegate);}this.refreshDelegate=this._handleRefresh.createDelegate(this,[_b,_c,_d]);this.on("activate",this._handleRefresh.createDelegate(this,[_b,_c,_d]));return this.el.getUpdateManager();},_handleRefresh:function(_e,_f,_10){if(!_10||!this.loaded){var _11=this.el.getUpdateManager();_11.update(_e,_f,this._setLoaded.createDelegate(this));}},_setLoaded:function(){this.loaded=true;},getId:function(){return this.el.id;},getEl:function(){return this.el;},adjustForComponents:function(_12,_13){if(this.resizeEl!=this.el){_12-=this.el.getFrameWidth("lr");_13-=this.el.getFrameWidth("tb");}if(this.toolbar){var te=this.toolbar.getEl();_13-=te.getHeight();te.setWidth(_12);}if(this.adjustments){_12+=this.adjustments[0];_13+=this.adjustments[1];}return {"width":_12,"height":_13};},setSize:function(_15,_16){if(this.fitToFrame&&!this.ignoreResize(_15,_16)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(_15,_16);}var _17=this.adjustForComponents(_15,_16);this.resizeEl.setSize(this.autoWidth?"auto":_17.width,_17.height);this.fireEvent("resize",this,_17.width,_17.height);}},getTitle:function(){return this.title;},setTitle:function(_18){this.title=_18;if(this.region){this.region.updatePanelTitle(this,_18);}},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();}},destroy:function(){this.el.removeAllListeners();var _19=document.createElement("span");_19.appendChild(this.el.dom);_19.innerHTML="";this.el.remove();this.el=null;}});Ext.GridPanel=function(_1a,_1b){this.wrapper=Ext.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(_1a.container.dom);Ext.GridPanel.superclass.constructor.call(this,this.wrapper,_1b);if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}_1a.monitorWindowResize=false;_1a.autoHeight=false;_1a.autoWidth=false;this.grid=_1a;this.grid.container.replaceClass("x-layout-inactive-content","x-layout-component-panel");};Ext.extend(Ext.GridPanel,Ext.ContentPanel,{getId:function(){return this.grid.id;},getGrid:function(){return this.grid;},setSize:function(_1c,_1d){if(!this.ignoreResize(_1c,_1d)){var _1e=this.grid;var _1f=this.adjustForComponents(_1c,_1d);_1e.container.setSize(_1f.width,_1f.height);_1e.autoSize();}},beforeSlide:function(){this.grid.getView().scroller.clip();},afterSlide:function(){this.grid.getView().scroller.unclip();},destroy:function(){this.grid.destroy();delete this.grid;Ext.GridPanel.superclass.destroy.call(this);}});Ext.NestedLayoutPanel=function(_20,_21){Ext.NestedLayoutPanel.superclass.constructor.call(this,_20.getEl(),_21);_20.monitorWindowResize=false;this.layout=_20;this.layout.getEl().addClass("x-layout-nested-layout");};Ext.extend(Ext.NestedLayoutPanel,Ext.ContentPanel,{setSize:function(_22,_23){if(!this.ignoreResize(_22,_23)){var _24=this.adjustForComponents(_22,_23);var el=this.layout.getEl();el.setSize(_24.width,_24.height);var _26=el.dom.offsetWidth;this.layout.layout();if(Ext.isIE&&!this.initialized){this.initialized=true;this.layout.layout();}}},getLayout:function(){return this.layout;}});Ext.ScrollPanel=function(el,_28,_29){_28=_28||{};_28.fitToFrame=true;Ext.ScrollPanel.superclass.constructor.call(this,el,_28,_29);this.el.dom.style.overflow="hidden";var _2a=this.el.wrap({cls:"x-scroller x-layout-inactive-content"});this.el.removeClass("x-layout-inactive-content");this.el.on("mousewheel",this.onWheel,this);var up=_2a.createChild({cls:"x-scroller-up",html:"&#160;"},this.el.dom);var _2c=_2a.createChild({cls:"x-scroller-down",html:"&#160;"});up.unselectable();_2c.unselectable();up.on("click",this.scrollUp,this);_2c.on("click",this.scrollDown,this);up.addClassOnOver("x-scroller-btn-over");_2c.addClassOnOver("x-scroller-btn-over");up.addClassOnClick("x-scroller-btn-click");_2c.addClassOnClick("x-scroller-btn-click");this.adjustments=[0,-(up.getHeight()+_2c.getHeight())];this.resizeEl=this.el;this.el=_2a;this.up=up;this.down=_2c;};Ext.extend(Ext.ScrollPanel,Ext.ContentPanel,{increment:100,wheelIncrement:5,scrollUp:function(){this.resizeEl.scroll("up",this.increment,{callback:this.afterScroll,scope:this});},scrollDown:function(){this.resizeEl.scroll("down",this.increment,{callback:this.afterScroll,scope:this});},afterScroll:function(){var el=this.resizeEl;var t=el.dom.scrollTop,h=el.dom.scrollHeight,ch=el.dom.clientHeight;this.up[t==0?"addClass":"removeClass"]("x-scroller-btn-disabled");this.down[h-t<=ch?"addClass":"removeClass"]("x-scroller-btn-disabled");},setSize:function(){Ext.ScrollPanel.superclass.setSize.apply(this,arguments);this.afterScroll();},onWheel:function(e){var d=e.getWheelDelta();this.resizeEl.dom.scrollTop-=(d*this.wheelIncrement);this.afterScroll();e.stopEvent();},setContent:function(_33,_34){this.resizeEl.update(_33,_34);}});
+
+Ext.ReaderLayout=function(_1,_2){var c=_1||{size:{}};Ext.ReaderLayout.superclass.constructor.call(this,_2||document.body,{north:c.north!==false?Ext.apply({split:false,initialSize:32,titlebar:false},c.north):false,west:c.west!==false?Ext.apply({split:true,initialSize:200,minSize:175,maxSize:400,titlebar:true,collapsible:true,animate:true,margins:{left:5,right:0,bottom:5,top:5},cmargins:{left:5,right:5,bottom:5,top:5}},c.west):false,east:c.east!==false?Ext.apply({split:true,initialSize:200,minSize:175,maxSize:400,titlebar:true,collapsible:true,animate:true,margins:{left:0,right:5,bottom:5,top:5},cmargins:{left:5,right:5,bottom:5,top:5}},c.east):false,center:Ext.apply({tabPosition:"top",autoScroll:false,closeOnTab:true,titlebar:false,margins:{left:c.west!==false?0:5,right:c.east!==false?0:5,bottom:5,top:2}},c.center)});this.el.addClass("x-reader");this.beginUpdate();var _4=new Ext.BorderLayout(Ext.get(document.body).createChild(),{south:c.preview!==false?Ext.apply({split:true,initialSize:200,minSize:100,autoScroll:true,collapsible:true,titlebar:true,cmargins:{top:5,left:0,right:0,bottom:0}},c.preview):false,center:Ext.apply({autoScroll:false,titlebar:false,minHeight:200},c.listView)});this.add("center",new Ext.NestedLayoutPanel(_4,Ext.apply({title:_1.mainTitle||"",tabTip:""},_1.innerPanelCfg)));this.endUpdate();this.regions.preview=_4.getRegion("south");this.regions.listView=_4.getRegion("center");};Ext.extend(Ext.ReaderLayout,Ext.BorderLayout);
+
+Ext.grid.Grid=function(_1,_2){this.container=Ext.get(_1);this.container.update("");this.container.setStyle("overflow","hidden");this.container.addClass("x-grid-container");this.id=this.container.id;Ext.apply(this,_2);if(this.ds){this.dataSource=this.ds;delete this.ds;}if(this.cm){this.colModel=this.cm;delete this.cm;}if(this.sm){this.selModel=this.sm;delete this.sm;}if(this.width){this.container.setWidth(this.width);}if(this.height){this.container.setHeight(this.height);}this.events={"click":true,"dblclick":true,"contextmenu":true,"mousedown":true,"mouseup":true,"mouseover":true,"mouseout":true,"keypress":true,"keydown":true,"cellclick":true,"celldblclick":true,"rowclick":true,"rowdblclick":true,"headerclick":true,"headerdblclick":true,"rowcontextmenu":true,"cellcontextmenu":true,"headercontextmenu":true,"bodyscroll":true,"columnresize":true,"columnmove":true,"startdrag":true,"enddrag":true,"dragdrop":true,"dragover":true,"dragenter":true,"dragout":true};Ext.grid.Grid.superclass.constructor.call(this);};Ext.extend(Ext.grid.Grid,Ext.util.Observable,{minColumnWidth:25,autoSizeColumns:false,autoSizeHeaders:true,monitorWindowResize:true,maxRowsToMeasure:0,trackMouseOver:true,enableDragDrop:false,enableColumnMove:true,enableColumnHide:true,enableRowHeightSync:false,stripeRows:true,autoHeight:false,autoExpandColumn:false,autoExpandMin:50,autoExpandMax:1000,view:null,allowTextSelectionPattern:/INPUT|TEXTAREA|SELECT/i,loadMask:false,rendered:false,render:function(){var c=this.container;if((!c.dom.offsetHeight||c.dom.offsetHeight<20)||c.getStyle("height")=="auto"){this.autoHeight=true;}var _4=this.getView();_4.init(this);c.on("click",this.onClick,this);c.on("dblclick",this.onDblClick,this);c.on("contextmenu",this.onContextMenu,this);c.on("keydown",this.onKeyDown,this);this.relayEvents(c,["mousedown","mouseup","mouseover","mouseout","keypress"]);this.getSelectionModel().init(this);_4.render();if(this.loadMask){this.loadMask=new Ext.LoadMask(this.container,Ext.apply({store:this.dataSource},this.loadMask));}this.rendered=true;return this;},reconfigure:function(_5,_6){if(this.loadMask){this.loadMask.destroy();this.loadMask=new Ext.LoadMask(this.container,Ext.apply({store:_5},this.loadMask));}this.view.bind(_5,_6);this.dataSource=_5;this.colModel=_6;this.view.refresh(true);},onKeyDown:function(e){this.fireEvent("keydown",e);},destroy:function(_8,_9){if(this.loadMask){this.loadMask.destroy();}var c=this.container;c.removeAllListeners();this.view.destroy();this.colModel.purgeListeners();if(!_9){this.purgeListeners();}c.update("");if(_8===true){c.remove();}},processEvent:function(_b,e){this.fireEvent(_b,e);var t=e.getTarget();var v=this.view;var _f=v.findHeaderIndex(t);if(_f!==false){this.fireEvent("header"+_b,this,_f,e);}else{var row=v.findRowIndex(t);var _11=v.findCellIndex(t);if(row!==false){this.fireEvent("row"+_b,this,row,e);if(_11!==false){this.fireEvent("cell"+_b,this,row,_11,e);}}}},onClick:function(e){this.processEvent("click",e);},onContextMenu:function(e,t){this.processEvent("contextmenu",e);},onDblClick:function(e){this.processEvent("dblclick",e);},walkCells:function(row,col,_18,fn,_1a){var cm=this.colModel,_1c=cm.getColumnCount();var ds=this.dataSource,_1e=ds.getCount(),_1f=true;if(_18<0){if(col<0){row--;_1f=false;}while(row>=0){if(!_1f){col=_1c-1;}_1f=false;while(col>=0){if(fn.call(_1a||this,row,col,cm)===true){return [row,col];}col--;}row--;}}else{if(col>=_1c){row++;_1f=false;}while(row<_1e){if(!_1f){col=0;}_1f=false;while(col<_1c){if(fn.call(_1a||this,row,col,cm)===true){return [row,col];}col++;}row++;}}return null;},getSelections:function(){return this.selModel.getSelections();},autoSize:function(){if(this.rendered){this.view.layout();if(this.view.adjustForScroll){this.view.adjustForScroll();}}},stopEditing:function(){},getSelectionModel:function(){if(!this.selModel){this.selModel=new Ext.grid.RowSelectionModel();}return this.selModel;},getDataSource:function(){return this.dataSource;},getColumnModel:function(){return this.colModel;},getView:function(){if(!this.view){this.view=new Ext.grid.GridView();}return this.view;},getDragDropText:function(){var _20=this.selModel.getCount();return String.format(this.ddText,_20,_20==1?"":"s");}});Ext.grid.Grid.prototype.ddText="{0} selected row{1}";
+
+Ext.grid.AbstractGridView=function(){this.grid=null;this.events={"beforerowremoved":true,"beforerowsinserted":true,"beforerefresh":true,"rowremoved":true,"rowsinserted":true,"rowupdated":true,"refresh":true};Ext.grid.AbstractGridView.superclass.constructor.call(this);};Ext.extend(Ext.grid.AbstractGridView,Ext.util.Observable,{rowClass:"x-grid-row",cellClass:"x-grid-cell",tdClass:"x-grid-td",hdClass:"x-grid-hd",splitClass:"x-grid-hd-split",init:function(_1){this.grid=_1;var _2=this.grid.container.id;this.colSelector="#"+_2+" ."+this.cellClass+"-";this.tdSelector="#"+_2+" ."+this.tdClass+"-";this.hdSelector="#"+_2+" ."+this.hdClass+"-";this.splitSelector="#"+_2+" ."+this.splitClass+"-";},getColumnRenderers:function(){var _3=[];var cm=this.grid.colModel;var _5=cm.getColumnCount();for(var i=0;i<_5;i++){_3[i]=cm.getRenderer(i);}return _3;},getColumnIds:function(){var _7=[];var cm=this.grid.colModel;var _9=cm.getColumnCount();for(var i=0;i<_9;i++){_7[i]=cm.getColumnId(i);}return _7;},getDataIndexes:function(){if(!this.indexMap){this.indexMap=this.buildIndexMap();}return this.indexMap.colToData;},getColumnIndexByDataIndex:function(_b){if(!this.indexMap){this.indexMap=this.buildIndexMap();}return this.indexMap.dataToCol[_b];},setCSSStyle:function(_c,_d,_e){var _f="#"+this.grid.id+" .x-grid-col-"+_c;Ext.util.CSS.updateRule(_f,_d,_e);},generateRules:function(cm){var _11=[];for(var i=0,len=cm.getColumnCount();i<len;i++){var cid=cm.getColumnId(i);_11.push(this.colSelector,cid," {\n",cm.config[i].css,"}\n",this.tdSelector,cid," {\n}\n",this.hdSelector,cid," {\n}\n",this.splitSelector,cid," {\n}\n");}return Ext.util.CSS.createStyleSheet(_11.join(""));}});
+
+Ext.grid.GridView=function(_1){Ext.grid.GridView.superclass.constructor.call(this);this.el=null;Ext.apply(this,_1);};Ext.extend(Ext.grid.GridView,Ext.grid.AbstractGridView,{rowClass:"x-grid-row",cellClass:"x-grid-col",tdClass:"x-grid-td",hdClass:"x-grid-hd",splitClass:"x-grid-split",sortClasses:["sort-asc","sort-desc"],enableMoveAnim:false,hlColor:"C3DAF9",dh:Ext.DomHelper,fly:Ext.Element.fly,css:Ext.util.CSS,borderWidth:1,splitOffset:3,scrollIncrement:22,cellRE:/(?:.*?)x-grid-(?:hd|cell|csplit)-(?:[\d]+)-([\d]+)(?:.*?)/,findRE:/\s?(?:x-grid-hd|x-grid-col|x-grid-csplit)\s/,init:function(_2){Ext.grid.GridView.superclass.init.call(this,_2);this.bind(_2.dataSource,_2.colModel);_2.on("headerclick",this.handleHeaderClick,this);if(_2.trackMouseOver){_2.on("mouseover",this.onRowOver,this);_2.on("mouseout",this.onRowOut,this);}_2.cancelTextSelection=function(){};this.gridId=_2.id;var _3=this.templates||{};if(!_3.master){_3.master=new Ext.Template("<div class=\"x-grid\" hidefocus=\"true\">","<div class=\"x-grid-topbar\"></div>","<div class=\"x-grid-scroller\"><div></div></div>","<div class=\"x-grid-locked\">","<div class=\"x-grid-header\">{lockedHeader}</div>","<div class=\"x-grid-body\">{lockedBody}</div>","</div>","<div class=\"x-grid-viewport\">","<div class=\"x-grid-header\">{header}</div>","<div class=\"x-grid-body\">{body}</div>","</div>","<div class=\"x-grid-bottombar\"></div>","<a href=\"#\" class=\"x-grid-focus\" tabIndex=\"-1\"></a>","<div class=\"x-grid-resize-proxy\">&#160;</div>","</div>");_3.master.disableformats=true;}if(!_3.header){_3.header=new Ext.Template("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">","<tbody><tr class=\"x-grid-hd-row\">{cells}</tr></tbody>","</table>{splits}");_3.header.disableformats=true;}_3.header.compile();if(!_3.hcell){_3.hcell=new Ext.Template("<td class=\"x-grid-hd x-grid-td-{id} {cellId}\"><div title=\"{title}\" class=\"x-grid-hd-inner x-grid-hd-{id}\">","<div class=\"x-grid-hd-text\" unselectable=\"on\">{value}<img class=\"x-grid-sort-icon\" src=\"",Ext.BLANK_IMAGE_URL,"\" /></div>","</div></td>");_3.hcell.disableFormats=true;}_3.hcell.compile();if(!_3.hsplit){_3.hsplit=new Ext.Template("<div class=\"x-grid-split {splitId} x-grid-split-{id}\" style=\"{style}\" unselectable=\"on\">&#160;</div>");_3.hsplit.disableFormats=true;}_3.hsplit.compile();if(!_3.body){_3.body=new Ext.Template("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">","<tbody>{rows}</tbody>","</table>");_3.body.disableFormats=true;}_3.body.compile();if(!_3.row){_3.row=new Ext.Template("<tr class=\"x-grid-row {alt}\">{cells}</tr>");_3.row.disableFormats=true;}_3.row.compile();if(!_3.cell){_3.cell=new Ext.Template("<td class=\"x-grid-col x-grid-td-{id} {cellId} {css}\" tabIndex=\"0\">","<div class=\"x-grid-col-{id} x-grid-cell-inner\"><div class=\"x-grid-cell-text\" unselectable=\"on\" {attr}>{value}</div></div>","</td>");_3.cell.disableFormats=true;}_3.cell.compile();this.templates=_3;},bind:function(ds,cm){if(this.ds){this.ds.un("load",this.onLoad,this);this.ds.un("datachanged",this.onDataChange);this.ds.un("add",this.onAdd);this.ds.un("remove",this.onRemove);this.ds.un("update",this.onUpdate);this.ds.un("clear",this.onClear);}if(ds){ds.on("load",this.onLoad,this);ds.on("datachanged",this.onDataChange,this);ds.on("add",this.onAdd,this);ds.on("remove",this.onRemove,this);ds.on("update",this.onUpdate,this);ds.on("clear",this.onClear,this);}this.ds=ds;if(this.cm){this.cm.un("widthchange",this.updateColumns,this);this.cm.un("headerchange",this.updateHeaders,this);this.cm.un("hiddenchange",this.handleHiddenChange,this);this.cm.un("columnmoved",this.handleColumnMove,this);this.cm.un("columnlockchange",this.handleLockChange,this);}if(cm){this.generateRules(cm);cm.on("widthchange",this.updateColumns,this);cm.on("headerchange",this.updateHeaders,this);cm.on("hiddenchange",this.handleHiddenChange,this);cm.on("columnmoved",this.handleColumnMove,this);cm.on("columnlockchange",this.handleLockChange,this);}this.cm=cm;},onDataChange:function(){this.refresh();this.updateHeaderSortState();},onClear:function(){this.refresh();},onUpdate:function(ds,_7){this.refreshRow(_7);},refreshRow:function(_8){var ds=this.ds,_a;if(typeof _8=="number"){_a=_8;_8=ds.getAt(_a);}else{_a=ds.indexOf(_8);}var _b=this.getRowComposite(_a);var _c=[];this.insertRows(ds,_a,_a,true);this.onRemove(ds,_8,_a+1,true);this.syncRowHeights(_a,_a);this.layout();this.fireEvent("rowupdated",this,_a,_8);},onAdd:function(ds,_e,_f){this.insertRows(ds,_f,_f+(_e.length-1));},onRemove:function(ds,_11,_12,_13){if(_13!==true){this.fireEvent("beforerowremoved",this,_12,_11);}var bt=this.getBodyTable(),lt=this.getLockedTable();if(bt.rows[_12]){bt.firstChild.removeChild(bt.rows[_12]);}if(lt.rows[_12]){lt.firstChild.removeChild(lt.rows[_12]);}if(_13!==true){this.stripeRows(_12);this.syncRowHeights(_12,_12);this.layout();this.fireEvent("rowremoved",this,_12,_11);}},onLoad:function(){this.scrollToTop();},scrollToTop:function(){if(this.scroller){this.scroller.dom.scrollTop=0;this.syncScroll();}},getHeaderPanel:function(_16){if(_16){this.headerPanel.show();}return this.headerPanel;},getFooterPanel:function(_17){if(_17){this.footerPanel.show();}return this.footerPanel;},initElements:function(){var E=Ext.Element;var el=this.grid.container.dom.firstChild;var cs=el.childNodes;this.el=new E(el);this.headerPanel=new E(el.firstChild);this.headerPanel.enableDisplayMode("block");this.scroller=new E(cs[1]);this.scrollSizer=new E(this.scroller.dom.firstChild);this.lockedWrap=new E(cs[2]);this.lockedHd=new E(this.lockedWrap.dom.firstChild);this.lockedBody=new E(this.lockedWrap.dom.childNodes[1]);this.mainWrap=new E(cs[3]);this.mainHd=new E(this.mainWrap.dom.firstChild);this.mainBody=new E(this.mainWrap.dom.childNodes[1]);this.footerPanel=new E(cs[4]);this.footerPanel.enableDisplayMode("block");this.focusEl=new E(cs[5]);this.focusEl.swallowEvent("click",true);this.resizeProxy=new E(cs[6]);this.headerSelector=String.format("#{0} td.x-grid-hd, #{1} td.x-grid-hd",this.lockedHd.id,this.mainHd.id);this.splitterSelector=String.format("#{0} div.x-grid-split, #{1} div.x-grid-split",this.lockedHd.id,this.mainHd.id);},getHeaderCell:function(_1b){return Ext.DomQuery.select(this.headerSelector)[_1b];},getHeaderCellMeasure:function(_1c){return this.getHeaderCell(_1c).firstChild;},getHeaderCellText:function(_1d){return this.getHeaderCell(_1d).firstChild.firstChild;},getLockedTable:function(){return this.lockedBody.dom.firstChild;},getBodyTable:function(){return this.mainBody.dom.firstChild;},getLockedRow:function(_1e){return this.getLockedTable().rows[_1e];},getRow:function(_1f){return this.getBodyTable().rows[_1f];},getRowComposite:function(_20){if(!this.rowEl){this.rowEl=new Ext.CompositeElementLite();}var els=[],_22,_23;if(_22=this.getLockedRow(_20)){els.push(_22);}if(_23=this.getRow(_20)){els.push(_23);}this.rowEl.elements=els;return this.rowEl;},getCell:function(_24,_25){var _26=this.cm.getLockedCount();var _27;if(_25<_26){_27=this.lockedBody.dom.firstChild;}else{_27=this.mainBody.dom.firstChild;_25-=_26;}return _27.rows[_24].childNodes[_25];},getCellText:function(_28,_29){return this.getCell(_28,_29).firstChild.firstChild;},getCellBox:function(_2a){var b=this.fly(_2a).getBox();if(Ext.isOpera){b.y=_2a.offsetTop+this.mainBody.getY();}return b;},getCellIndex:function(_2c){var id=String(_2c.className).match(this.cellRE);if(id){return parseInt(id[1],10);}return 0;},findHeaderIndex:function(n){var r=Ext.fly(n).findParent("td."+this.hdClass,6);return r?this.getCellIndex(r):false;},findHeaderCell:function(n){var r=Ext.fly(n).findParent("td."+this.hdClass,6);return r?r:false;},findRowIndex:function(n){if(!n){return false;}var r=Ext.fly(n).findParent("tr."+this.rowClass,6);return r?r.rowIndex:false;},findCellIndex:function(_34){var _35=this.el.dom;while(_34&&_34!=_35){if(this.findRE.test(_34.className)){return this.getCellIndex(_34);}_34=_34.parentNode;}return false;},getColumnId:function(_36){return this.cm.getColumnId(_36);},getSplitters:function(){if(this.splitterSelector){return Ext.DomQuery.select(this.splitterSelector);}else{return null;}},getSplitter:function(_37){return this.getSplitters()[_37];},onRowOver:function(e,t){var row;if((row=this.findRowIndex(t))!==false){this.getRowComposite(row).addClass("x-grid-row-over");}},onRowOut:function(e,t){var row;if((row=this.findRowIndex(t))!==false&&row!==this.findRowIndex(e.getRelatedTarget())){this.getRowComposite(row).removeClass("x-grid-row-over");}},renderHeaders:function(){var cm=this.cm;var ct=this.templates.hcell,ht=this.templates.header,st=this.templates.hsplit;var cb=[],lb=[],sb=[],lsb=[],p={};for(var i=0,len=cm.getColumnCount();i<len;i++){p.cellId="x-grid-hd-0-"+i;p.splitId="x-grid-csplit-0-"+i;p.id=cm.getColumnId(i);p.title=cm.getColumnTooltip(i)||"";p.value=cm.getColumnHeader(i)||"";p.style=(this.grid.enableColumnResize===false||!cm.isResizable(i)||cm.isFixed(i))?"cursor:default":"";if(!cm.isLocked(i)){cb[cb.length]=ct.apply(p);sb[sb.length]=st.apply(p);}else{lb[lb.length]=ct.apply(p);lsb[lsb.length]=st.apply(p);}}return [ht.apply({cells:lb.join(""),splits:lsb.join("")}),ht.apply({cells:cb.join(""),splits:sb.join("")})];},updateHeaders:function(){var _49=this.renderHeaders();this.lockedHd.update(_49[0]);this.mainHd.update(_49[1]);},focusRow:function(row){var x=this.scroller.dom.scrollLeft;this.focusCell(row,0,false);this.scroller.dom.scrollLeft=x;},focusCell:function(row,col,_4e){var el=this.ensureVisible(row,col,_4e);this.focusEl.alignTo(el,"tl-tl");this.focusEl.focus.defer(1,this.focusEl);},ensureVisible:function(row,col,_52){if(typeof row!="number"){row=row.rowIndex;}if(row<0&&row>=this.ds.getCount()){return;}col=(col!==undefined?col:0);var cm=this.grid.colModel;while(cm.isHidden(col)){col++;}var el=this.getCell(row,col);if(!el){return;}var c=this.scroller.dom;var _56=parseInt(el.offsetTop,10);var _57=parseInt(el.offsetLeft,10);var _58=_56+el.offsetHeight;var _59=_57+el.offsetWidth;var ch=c.clientHeight-this.mainHd.dom.offsetHeight;var _5b=parseInt(c.scrollTop,10);var _5c=parseInt(c.scrollLeft,10);var _5d=_5b+ch;var _5e=_5c+c.clientWidth;if(_56<_5b){c.scrollTop=_56;}else{if(_58>_5d){c.scrollTop=_58-ch;}}if(_52!==false){if(_57<_5c){c.scrollLeft=_57;}else{if(_59>_5e){c.scrollLeft=_59-c.clientWidth;}}}return el;},updateColumns:function(){this.grid.stopEditing();var cm=this.grid.colModel,_60=this.getColumnIds();var pos=0;for(var i=0,len=cm.getColumnCount();i<len;i++){var w=cm.getColumnWidth(i);this.css.updateRule(this.colSelector+_60[i],"width",(w-this.borderWidth)+"px");this.css.updateRule(this.hdSelector+_60[i],"width",(w-this.borderWidth)+"px");}this.updateSplitters();},updateSplitters:function(){var cm=this.cm,s=this.getSplitters();if(s){var pos=0,_68=true;for(var i=0,len=cm.getColumnCount();i<len;i++){if(cm.isHidden(i)){continue;}var w=cm.getColumnWidth(i);if(!cm.isLocked(i)&&_68){pos=0;_68=false;}pos+=w;s[i].style.left=(pos-this.splitOffset)+"px";}}},handleHiddenChange:function(_6c,_6d,_6e){if(_6e){this.hideColumn(_6d);}else{this.unhideColumn(_6d);}},hideColumn:function(_6f){var cid=this.getColumnId(_6f);this.css.updateRule(this.tdSelector+cid,"display","none");this.css.updateRule(this.splitSelector+cid,"display","none");if(Ext.isSafari){this.updateHeaders();}this.updateSplitters();this.layout();},unhideColumn:function(_71){var cid=this.getColumnId(_71);this.css.updateRule(this.tdSelector+cid,"display","");this.css.updateRule(this.splitSelector+cid,"display","");if(Ext.isSafari){this.updateHeaders();}this.updateSplitters();this.layout();},insertRows:function(dm,_74,_75,_76){if(_74==0&&_75==dm.getCount()-1){this.refresh();}else{if(!_76){this.fireEvent("beforerowsinserted",this,_74,_75);}var s=this.getScrollState();var _78=this.renderRows(_74,_75);this.bufferRows(_78[0],this.getLockedTable(),_74);this.bufferRows(_78[1],this.getBodyTable(),_74);this.restoreScroll(s);if(!_76){this.fireEvent("rowsinserted",this,_74,_75);this.syncRowHeights(_74,_75);this.stripeRows(_74);this.layout();}}},bufferRows:function(_79,_7a,_7b){var _7c=null,_7d=_7a.rows,_7e=_7a.tBodies[0];if(_7b<_7d.length){_7c=_7d[_7b];}var b=document.createElement("div");b.innerHTML="<table><tbody>"+_79+"</tbody></table>";var _80=b.firstChild.rows;for(var i=0,len=_80.length;i<len;i++){if(_7c){_7e.insertBefore(_80[0],_7c);}else{_7e.appendChild(_80[0]);}}b.innerHTML="";b=null;},deleteRows:function(dm,_84,_85){if(dm.getRowCount()<1){this.fireEvent("beforerefresh",this);this.mainBody.update("");this.lockedBody.update("");this.fireEvent("refresh",this);}else{this.fireEvent("beforerowsdeleted",this,_84,_85);var bt=this.getBodyTable();var _87=bt.firstChild;var _88=bt.rows;for(var _89=_84;_89<=_85;_89++){_87.removeChild(_88[_84]);}this.stripeRows(_84);this.fireEvent("rowsdeleted",this,_84,_85);}},updateRows:function(_8a,_8b,_8c){var s=this.getScrollState();this.refresh();this.restoreScroll(s);},handleSort:function(_8e,_8f,_90,_91){if(!_91){this.refresh();}this.updateHeaderSortState();},getScrollState:function(){var sb=this.scroller.dom;return {left:sb.scrollLeft,top:sb.scrollTop};},stripeRows:function(_93){if(!this.grid.stripeRows||this.ds.getCount()<1){return;}_93=_93||0;var _94=this.getBodyTable().rows;var _95=this.getLockedTable().rows;var cls=" x-grid-row-alt ";for(var i=_93,len=_94.length;i<len;i++){var row=_94[i],_9a=_95[i];var _9b=((i+1)%2==0);var _9c=(" "+row.className+" ").indexOf(cls)!=-1;if(_9b==_9c){continue;}if(_9b){row.className+=" x-grid-row-alt";}else{row.className=row.className.replace("x-grid-row-alt","");}if(_9a){_9a.className=row.className;}}},restoreScroll:function(_9d){var sb=this.scroller.dom;sb.scrollLeft=_9d.left;sb.scrollTop=_9d.top;this.syncScroll();},syncScroll:function(){var sb=this.scroller.dom;var sh=this.mainHd.dom;var bs=this.mainBody.dom;var lv=this.lockedBody.dom;sh.scrollLeft=bs.scrollLeft=sb.scrollLeft;lv.scrollTop=bs.scrollTop=sb.scrollTop;},handleScroll:function(e){this.syncScroll();var sb=this.scroller.dom;this.grid.fireEvent("bodyscroll",sb.scrollLeft,sb.scrollTop);e.stopEvent();},handleWheel:function(e){var d=e.getWheelDelta();this.scroller.dom.scrollTop-=d*22;this.lockedBody.dom.scrollTop=this.mainBody.dom.scrollTop=this.scroller.dom.scrollTop;e.stopEvent();},renderRows:function(_a7,_a8){var g=this.grid,cm=g.colModel,ds=g.dataSource,_ac=g.stripeRows;var _ad=cm.getColumnCount();if(ds.getCount()<1){return ["",""];}var cs=[];for(var i=0;i<_ad;i++){var _b0=cm.getDataIndex(i);cs[i]={name:typeof _b0=="undefined"?ds.fields.get(i).name:_b0,renderer:cm.getRenderer(i),id:cm.getColumnId(i),locked:cm.isLocked(i)};}_a7=_a7||0;_a8=typeof _a8=="undefined"?ds.getCount()-1:_a8;var rs=ds.getRange(_a7,_a8);return this.doRender(cs,rs,ds,_a7,_ad,_ac);},doRender:Ext.isGecko?function(cs,rs,ds,_b5,_b6,_b7){var ts=this.templates,ct=ts.cell,rt=ts.row;var buf="",_bc="",cb,lcb,c,p={},rp={},r;for(var j=0,len=rs.length;j<len;j++){r=rs[j],cb="",lcb="",rowIndex=(j+_b5);for(var i=0;i<_b6;i++){c=cs[i];p.cellId="x-grid-cell-"+rowIndex+"-"+i;p.id=c.id;p.css=p.attr="";p.value=c.renderer(r.data[c.name],p,r,rowIndex,i,ds);if(p.value==undefined||p.value===""){p.value="&#160;";}if(r.dirty&&typeof r.modified[c.name]!=="undefined"){p.css+=p.css?" x-grid-dirty-cell":"x-grid-dirty-cell";}var _c6=ct.apply(p);if(!c.locked){cb+=_c6;}else{lcb+=_c6;}}var alt=[];if(_b7&&((rowIndex+1)%2==0)){alt[0]="x-grid-row-alt";}if(r.dirty){alt[1]=" x-grid-dirty-row";}rp.cells=lcb;if(this.getRowClass){alt[2]=this.getRowClass(r,rowIndex);}rp.alt=alt.join(" ");_bc+=rt.apply(rp);rp.cells=cb;buf+=rt.apply(rp);}return [_bc,buf];}:function(cs,rs,ds,_cb,_cc,_cd){var ts=this.templates,ct=ts.cell,rt=ts.row;var buf=[],_d2=[],cb,lcb,c,p={},rp={},r;for(var j=0,len=rs.length;j<len;j++){r=rs[j],cb=[],lcb=[],rowIndex=(j+_cb);for(var i=0;i<_cc;i++){c=cs[i];p.cellId="x-grid-cell-"+rowIndex+"-"+i;p.id=c.id;p.css=p.attr="";p.value=c.renderer(r.data[c.name],p,r,rowIndex,i,ds);if(p.value==undefined||p.value===""){p.value="&#160;";}if(r.dirty&&typeof r.modified[c.name]!=="undefined"){p.css+=p.css?" x-grid-dirty-cell":"x-grid-dirty-cell";}var _dc=ct.apply(p);if(!c.locked){cb[cb.length]=_dc;}else{lcb[lcb.length]=_dc;}}var alt=[];if(_cd&&((rowIndex+1)%2==0)){alt[0]="x-grid-row-alt";}if(r.dirty){alt[1]=" x-grid-dirty-row";}rp.cells=lcb;if(this.getRowClass){alt[2]=this.getRowClass(r,rowIndex);}rp.alt=alt.join(" ");rp.cells=lcb.join("");_d2[_d2.length]=rt.apply(rp);rp.cells=cb.join("");buf[buf.length]=rt.apply(rp);}return [_d2.join(""),buf.join("")];},renderBody:function(){var _de=this.renderRows();var bt=this.templates.body;return [bt.apply({rows:_de[0]}),bt.apply({rows:_de[1]})];},refresh:function(_e0){this.fireEvent("beforerefresh",this);this.grid.stopEditing();var _e1=this.renderBody();this.lockedBody.update(_e1[0]);this.mainBody.update(_e1[1]);if(_e0===true){this.updateHeaders();this.updateColumns();this.updateSplitters();this.updateHeaderSortState();}this.syncRowHeights();this.layout();this.fireEvent("refresh",this);},handleColumnMove:function(cm,_e3,_e4){this.indexMap=null;var s=this.getScrollState();this.refresh(true);this.restoreScroll(s);this.afterMove(_e4);},afterMove:function(_e6){if(this.enableMoveAnim&&Ext.enableFx){this.fly(this.getHeaderCell(_e6).firstChild).highlight(this.hlColor);}},updateCell:function(dm,_e8,_e9){var _ea=this.getColumnIndexByDataIndex(_e9);if(typeof _ea=="undefined"){return;}var cm=this.grid.colModel;var _ec=this.getCell(_e8,_ea);var _ed=this.getCellText(_e8,_ea);var p={cellId:"x-grid-cell-"+_e8+"-"+_ea,id:cm.getColumnId(_ea),css:_ea==cm.getColumnCount()-1?"x-grid-col-last":""};var _ef=cm.getRenderer(_ea);var val=_ef(dm.getValueAt(_e8,_e9),p,_e8,_ea,dm);if(typeof val=="undefined"||val===""){val="&#160;";}_ed.innerHTML=val;_ec.className=this.cellClass+" "+p.cellId+" "+p.css;this.syncRowHeights(_e8,_e8);},calcColumnWidth:function(_f1,_f2){var _f3=0;if(this.grid.autoSizeHeaders){var h=this.getHeaderCellMeasure(_f1);_f3=Math.max(_f3,h.scrollWidth);}var tb,_f6;if(this.cm.isLocked(_f1)){tb=this.getLockedTable();_f6=_f1;}else{tb=this.getBodyTable();_f6=_f1-this.cm.getLockedCount();}if(tb&&tb.rows){var _f7=tb.rows;var _f8=Math.min(_f2||_f7.length,_f7.length);for(var i=0;i<_f8;i++){var _fa=_f7[i].childNodes[_f6].firstChild;_f3=Math.max(_f3,_fa.scrollWidth);}}return _f3+5;},autoSizeColumn:function(_fb,_fc,_fd){if(this.cm.isHidden(_fb)){return;}if(_fc){var cid=this.cm.getColumnId(_fb);this.css.updateRule(this.colSelector+cid,"width",this.grid.minColumnWidth+"px");if(this.grid.autoSizeHeaders){this.css.updateRule(this.hdSelector+cid,"width",this.grid.minColumnWidth+"px");}}var _ff=this.calcColumnWidth(_fb);this.cm.setColumnWidth(_fb,Math.max(this.grid.minColumnWidth,_ff),_fd);if(!_fd){this.grid.fireEvent("columnresize",_fb,_ff);}},autoSizeColumns:function(){var cm=this.grid.colModel;var _101=cm.getColumnCount();for(var i=0;i<_101;i++){this.autoSizeColumn(i,true,true);}if(cm.getTotalWidth()<this.scroller.dom.clientWidth){this.fitColumns();}else{this.updateColumns();this.layout();}},fitColumns:function(_103){var cm=this.grid.colModel;var _105=cm.getColumnCount();var cols=[];var _107=0;var i,w;for(i=0;i<_105;i++){if(!cm.isHidden(i)&&!cm.isFixed(i)){w=cm.getColumnWidth(i);cols.push(i);cols.push(w);_107+=w;}}var _10a=Math.min(this.scroller.dom.clientWidth,this.el.getWidth());if(_103){_10a-=17;}var frac=(_10a-cm.getTotalWidth())/_107;while(cols.length){w=cols.pop();i=cols.pop();cm.setColumnWidth(i,Math.floor(w+w*frac),true);}this.updateColumns();this.layout();},onRowSelect:function(_10c){var row=this.getRowComposite(_10c);row.addClass("x-grid-row-selected");},onRowDeselect:function(_10e){var row=this.getRowComposite(_10e);row.removeClass("x-grid-row-selected");},onCellSelect:function(row,col){var cell=this.getCell(row,col);if(cell){Ext.fly(cell).addClass("x-grid-cell-selected");}},onCellDeselect:function(row,col){var cell=this.getCell(row,col);if(cell){Ext.fly(cell).removeClass("x-grid-cell-selected");}},updateHeaderSortState:function(){var _116=this.ds.getSortState();if(!_116){return;}this.sortState=_116;var _117=this.cm.findColumnIndex(_116.field);if(_117!=-1){var _118=_116.direction;var sc=this.sortClasses;var hds=this.el.select(this.headerSelector).removeClass(sc);hds.item(_117).addClass(sc[_118=="DESC"?1:0]);}},handleHeaderClick:function(g,_11c){if(this.headersDisabled){return;}var dm=g.dataSource,cm=g.colModel;if(!cm.isSortable(_11c)){return;}g.stopEditing();dm.sort(cm.getDataIndex(_11c));},destroy:function(){if(this.colMenu){this.colMenu.removeAll();Ext.menu.MenuMgr.unregister(this.colMenu);this.colMenu.getEl().remove();delete this.colMenu;}if(this.hmenu){this.hmenu.removeAll();Ext.menu.MenuMgr.unregister(this.hmenu);this.hmenu.getEl().remove();delete this.hmenu;}if(this.grid.enableColumnMove){var dds=Ext.dd.DDM.ids["gridHeader"+this.grid.container.id];if(dds){for(var dd in dds){if(!dds[dd].config.isTarget&&dds[dd].dragElId){var elid=dds[dd].dragElId;dds[dd].unreg();Ext.get(elid).remove();}else{if(dds[dd].config.isTarget){dds[dd].proxyTop.remove();dds[dd].proxyBottom.remove();dds[dd].unreg();}}if(Ext.dd.DDM.locationCache[dd]){delete Ext.dd.DDM.locationCache[dd];}}delete Ext.dd.DDM.ids["gridHeader"+this.grid.container.id];}}this.bind(null,null);Ext.EventManager.removeResizeListener(this.onWindowResize,this);},handleLockChange:function(){this.refresh(true);},onDenyColumnLock:function(){},onDenyColumnHide:function(){},handleHdMenuClick:function(item){var _123=this.hdCtxIndex;var cm=this.cm,ds=this.ds;switch(item.id){case "asc":ds.sort(cm.getDataIndex(_123),"ASC");break;case "desc":ds.sort(cm.getDataIndex(_123),"DESC");break;case "lock":var lc=cm.getLockedCount();if(cm.getColumnCount(true)<=lc+1){this.onDenyColumnLock();return;}if(lc!=_123){cm.setLocked(_123,true,true);cm.moveColumn(_123,lc);this.grid.fireEvent("columnmove",_123,lc);}else{cm.setLocked(_123,true);}break;case "unlock":var lc=cm.getLockedCount();if((lc-1)!=_123){cm.setLocked(_123,false,true);cm.moveColumn(_123,lc-1);this.grid.fireEvent("columnmove",_123,lc-1);}else{cm.setLocked(_123,false);}break;default:_123=cm.getIndexById(item.id.substr(4));if(_123!=-1){if(item.checked&&cm.getColumnCount(true)<=1){this.onDenyColumnHide();return false;}cm.setHidden(_123,item.checked);}}return true;},beforeColMenuShow:function(){var cm=this.cm,_128=cm.getColumnCount();this.colMenu.removeAll();for(var i=0;i<_128;i++){this.colMenu.add(new Ext.menu.CheckItem({id:"col-"+cm.getColumnId(i),text:cm.getColumnHeader(i),checked:!cm.isHidden(i),hideOnClick:false}));}},handleHdCtx:function(g,_12b,e){e.stopEvent();var hd=this.getHeaderCell(_12b);this.hdCtxIndex=_12b;var ms=this.hmenu.items,cm=this.cm;ms.get("asc").setDisabled(!cm.isSortable(_12b));ms.get("desc").setDisabled(!cm.isSortable(_12b));if(this.grid.enableColLock!==false){ms.get("lock").setDisabled(cm.isLocked(_12b));ms.get("unlock").setDisabled(!cm.isLocked(_12b));}this.hmenu.show(hd,"tl-bl");},handleHdOver:function(e){var hd=this.findHeaderCell(e.getTarget());if(hd&&!this.headersDisabled){if(this.grid.colModel.isSortable(this.getCellIndex(hd))){this.fly(hd).addClass("x-grid-hd-over");}}},handleHdOut:function(e){var hd=this.findHeaderCell(e.getTarget());if(hd){this.fly(hd).removeClass("x-grid-hd-over");}},handleSplitDblClick:function(e,t){var i=this.getCellIndex(t);if(this.grid.enableColumnResize!==false&&this.cm.isResizable(i)&&!this.cm.isFixed(i)){this.autoSizeColumn(i,true);this.layout();}},render:function(){var cm=this.cm;var _138=cm.getColumnCount();if(this.grid.monitorWindowResize===true){Ext.EventManager.onWindowResize(this.onWindowResize,this,true);}var _139=this.renderHeaders();var body=this.templates.body.apply({rows:""});var html=this.templates.master.apply({lockedBody:body,body:body,lockedHeader:_139[0],header:_139[1]});this.updateColumns();this.grid.container.dom.innerHTML=html;this.initElements();this.scroller.on("scroll",this.handleScroll,this);this.lockedBody.on("mousewheel",this.handleWheel,this);this.mainBody.on("mousewheel",this.handleWheel,this);this.mainHd.on("mouseover",this.handleHdOver,this);this.mainHd.on("mouseout",this.handleHdOut,this);this.mainHd.on("dblclick",this.handleSplitDblClick,this,{delegate:"."+this.splitClass});this.lockedHd.on("mouseover",this.handleHdOver,this);this.lockedHd.on("mouseout",this.handleHdOut,this);this.lockedHd.on("dblclick",this.handleSplitDblClick,this,{delegate:"."+this.splitClass});if(this.grid.enableColumnResize!==false&&Ext.grid.SplitDragZone){new Ext.grid.SplitDragZone(this.grid,this.lockedHd.dom,this.mainHd.dom);}this.updateSplitters();if(this.grid.enableColumnMove&&Ext.grid.HeaderDragZone){new Ext.grid.HeaderDragZone(this.grid,this.lockedHd.dom,this.mainHd.dom);new Ext.grid.HeaderDropZone(this.grid,this.lockedHd.dom,this.mainHd.dom);}if(this.grid.enableCtxMenu!==false&&Ext.menu.Menu){this.hmenu=new Ext.menu.Menu({id:this.grid.id+"-hctx"});this.hmenu.add({id:"asc",text:this.sortAscText,cls:"xg-hmenu-sort-asc"},{id:"desc",text:this.sortDescText,cls:"xg-hmenu-sort-desc"},"separator");if(this.grid.enableColLock!==false){this.hmenu.add({id:"lock",text:this.lockText,cls:"xg-hmenu-lock"},{id:"unlock",text:this.unlockText,cls:"xg-hmenu-unlock"},"separator");}if(this.grid.enableColumnHide!==false){this.colMenu=new Ext.menu.Menu({id:this.grid.id+"-hcols-menu"});this.colMenu.on("beforeshow",this.beforeColMenuShow,this);this.colMenu.on("itemclick",this.handleHdMenuClick,this);this.hmenu.add({id:"columns",text:this.columnsText,menu:this.colMenu});}this.hmenu.on("itemclick",this.handleHdMenuClick,this);this.grid.on("headercontextmenu",this.handleHdCtx,this);}if((this.grid.enableDragDrop||this.grid.enableDrag)&&Ext.grid.GridDragZone){var dd=new Ext.grid.GridDragZone(this.grid,{ddGroup:this.grid.ddGroup||"GridDD"});}for(var i=0;i<_138;i++){if(cm.isHidden(i)){this.hideColumn(i);}if(cm.config[i].align){this.css.updateRule(this.colSelector+i,"textAlign",cm.config[i].align);this.css.updateRule(this.hdSelector+i,"textAlign",cm.config[i].align);}}this.updateHeaderSortState();this.beforeInitialResize();this.layout(true);this.renderPhase2.defer(1,this);},renderPhase2:function(){this.refresh();if(this.grid.autoSizeColumns){this.autoSizeColumns();}},beforeInitialResize:function(){},onColumnSplitterMoved:function(i,w){this.userResized=true;var cm=this.grid.colModel;cm.setColumnWidth(i,w,true);var cid=cm.getColumnId(i);this.css.updateRule(this.colSelector+cid,"width",(w-this.borderWidth)+"px");this.css.updateRule(this.hdSelector+cid,"width",(w-this.borderWidth)+"px");this.updateSplitters();this.layout();this.grid.fireEvent("columnresize",i,w);},syncRowHeights:function(_142,_143){if(this.grid.enableRowHeightSync===true&&this.cm.getLockedCount()>0){_142=_142||0;var _144=this.getBodyTable().rows;var _145=this.getLockedTable().rows;var len=_144.length-1;_143=Math.min(_143||len,len);for(var i=_142;i<=_143;i++){var m=_144[i],l=_145[i];var h=Math.max(m.offsetHeight,l.offsetHeight);m.style.height=l.style.height=h+"px";}}},layout:function(_14b,_14c){var g=this.grid;var auto=g.autoHeight;var _14f=16;var c=g.container,cm=this.cm,_152=g.autoExpandColumn,gv=this;var _154=this.cm.isLocked(0);var tbh=this.headerPanel.getHeight();var bbh=this.footerPanel.getHeight();if(auto){var ch=this.getBodyTable().offsetHeight+tbh+bbh+this.mainHd.getHeight();var _158=ch+c.getBorderWidth("tb");if(g.maxHeight){_158=Math.min(g.maxHeight,_158);}c.setHeight(_158);}if(g.autoWidth){c.setWidth(cm.getTotalWidth()+c.getBorderWidth("lr"));}var s=this.scroller;var _15a=c.getSize(true);this.el.setSize(_15a.width,_15a.height);this.headerPanel.setWidth(_15a.width);this.footerPanel.setWidth(_15a.width);var _15b=this.mainHd.getHeight();var vw=_15a.width;var vh=_15a.height-(tbh+bbh);s.setSize(vw,vh);var bt=this.getBodyTable();var _15f=_154?Math.max(this.getLockedTable().offsetWidth,this.lockedHd.dom.firstChild.offsetWidth):0;var _160=bt.offsetHeight;var _161=_15f+bt.offsetWidth;var _162=false,_163=false;this.scrollSizer.setSize(_161,_160+_15b);var lw=this.lockedWrap,mw=this.mainWrap;var lb=this.lockedBody,mb=this.mainBody;setTimeout(function(){var t=s.dom.offsetTop;var w=s.dom.clientWidth,h=s.dom.clientHeight;lw.setTop(t);lw.setSize(_15f,h);mw.setLeftTop(_15f,t);mw.setSize(w-_15f,h);lb.setHeight(h-_15b);mb.setHeight(h-_15b);if(_14c!==true&&!gv.userResized&&_152){var ci=cm.getIndexById(_152);var tw=cm.getTotalWidth(false);var _16d=cm.getColumnWidth(ci);var cw=Math.min(Math.max(((w-tw)+_16d-2)-(w<=s.dom.offsetWidth?0:18),g.autoExpandMin),g.autoExpandMax);if(_16d!=cw){cm.setColumnWidth(ci,cw,true);gv.css.updateRule(gv.colSelector+_152,"width",(cw-gv.borderWidth)+"px");gv.css.updateRule(gv.hdSelector+_152,"width",(cw-gv.borderWidth)+"px");gv.updateSplitters();gv.layout(false,true);}}if(_14b){lw.show();mw.show();}},10);},onWindowResize:function(){if(!this.grid.monitorWindowResize||this.grid.autoHeight){return;}this.layout();},appendFooter:function(_16f){return null;},sortAscText:"Sort Ascending",sortDescText:"Sort Descending",lockText:"Lock Column",unlockText:"Unlock Column",columnsText:"Columns"});
+
+Ext.grid.HeaderDragZone=function(_1,hd,_3){this.grid=_1;this.view=_1.getView();this.ddGroup="gridHeader"+this.grid.container.id;Ext.grid.HeaderDragZone.superclass.constructor.call(this,hd);this.setHandleElId(Ext.id(hd));this.setOuterHandleElId(Ext.id(_3));this.scroll=false;};Ext.extend(Ext.grid.HeaderDragZone,Ext.dd.DragZone,{maxDragWidth:120,getDragData:function(e){var t=Ext.lib.Event.getTarget(e);var h=this.view.findHeaderCell(t);if(h){return {ddel:h.firstChild,header:h};}return false;},onInitDrag:function(e){var _8=this.dragData.ddel.cloneNode(true);_8.style.width=Math.min(this.dragData.header.offsetWidth,this.maxDragWidth)+"px";this.proxy.update(_8);return true;}});Ext.grid.HeaderDropZone=function(_9,hd,_b){this.grid=_9;this.view=_9.getView();this.proxyTop=Ext.DomHelper.append(document.body,{tag:"div",cls:"col-move-top",html:"&#160;"},true);this.proxyBottom=Ext.DomHelper.append(document.body,{tag:"div",cls:"col-move-bottom",html:"&#160;"},true);this.proxyTop.hide=this.proxyBottom.hide=function(){this.setLeftTop(-100,-100);this.setStyle("visibility","hidden");};this.ddGroup="gridHeader"+this.grid.container.id;Ext.grid.HeaderDropZone.superclass.constructor.call(this,_9.container.dom);};Ext.extend(Ext.grid.HeaderDropZone,Ext.dd.DropZone,{proxyOffsets:[-4,-9],fly:Ext.Element.fly,getTargetFromEvent:function(e){var t=Ext.lib.Event.getTarget(e);var _e=this.view.findCellIndex(t);if(_e!==false){return this.view.getHeaderCell(_e);}},nextVisible:function(h){var v=this.view,cm=this.grid.colModel;h=h.nextSibling;while(h){if(!cm.isHidden(v.getCellIndex(h))){return h;}h=h.nextSibling;}return null;},prevVisible:function(h){var v=this.view,cm=this.grid.colModel;h=h.prevSibling;while(h){if(!cm.isHidden(v.getCellIndex(h))){return h;}h=h.prevSibling;}return null;},positionIndicator:function(h,n,e){var x=Ext.lib.Event.getPageX(e);var r=Ext.lib.Dom.getRegion(n.firstChild);var px,pt,py=r.top+this.proxyOffsets[1];if((r.right-x)<=(r.right-r.left)/2){px=r.right+this.view.borderWidth;pt="after";}else{px=r.left;pt="before";}var _1d=this.view.getCellIndex(h);var _1e=this.view.getCellIndex(n);var _1f=this.grid.colModel.isLocked(_1e);if(pt=="after"){_1e++;}if(_1d<_1e){_1e--;}if(_1d==_1e&&(_1f==this.grid.colModel.isLocked(_1d))){return false;}px+=this.proxyOffsets[0];this.proxyTop.setLeftTop(px,py);this.proxyTop.show();if(!this.bottomOffset){this.bottomOffset=this.view.mainHd.getHeight();}this.proxyBottom.setLeftTop(px,py+this.proxyTop.dom.offsetHeight+this.bottomOffset);this.proxyBottom.show();return pt;},onNodeEnter:function(n,dd,e,_23){if(_23.header!=n){this.positionIndicator(_23.header,n,e);}},onNodeOver:function(n,dd,e,_27){var _28=false;if(_27.header!=n){_28=this.positionIndicator(_27.header,n,e);}if(!_28){this.proxyTop.hide();this.proxyBottom.hide();}return _28?this.dropAllowed:this.dropNotAllowed;},onNodeOut:function(n,dd,e,_2c){this.proxyTop.hide();this.proxyBottom.hide();},onNodeDrop:function(n,dd,e,_30){var h=_30.header;if(h!=n){var cm=this.grid.colModel;var x=Ext.lib.Event.getPageX(e);var r=Ext.lib.Dom.getRegion(n.firstChild);var pt=(r.right-x)<=((r.right-r.left)/2)?"after":"before";var _36=this.view.getCellIndex(h);var _37=this.view.getCellIndex(n);var _38=cm.isLocked(_37);if(pt=="after"){_37++;}if(_36<_37){_37--;}if(_36==_37&&(_38==cm.isLocked(_36))){return false;}cm.setLocked(_36,_38,true);cm.moveColumn(_36,_37);this.grid.fireEvent("columnmove",_36,_37);return true;}return false;}});
+
+Ext.grid.SplitDragZone=function(_1,hd,_3){this.grid=_1;this.view=_1.getView();this.proxy=this.view.resizeProxy;Ext.grid.SplitDragZone.superclass.constructor.call(this,hd,"gridSplitters"+this.grid.container.id,{dragElId:Ext.id(this.proxy.dom),resizeFrame:false});this.setHandleElId(Ext.id(hd));this.setOuterHandleElId(Ext.id(_3));this.scroll=false;};Ext.extend(Ext.grid.SplitDragZone,Ext.dd.DDProxy,{fly:Ext.Element.fly,b4StartDrag:function(x,y){this.view.headersDisabled=true;this.proxy.setHeight(this.view.mainWrap.getHeight());var w=this.cm.getColumnWidth(this.cellIndex);var _7=Math.max(w-this.grid.minColumnWidth,0);this.resetConstraints();this.setXConstraint(_7,1000);this.setYConstraint(0,0);this.minX=x-_7;this.maxX=x+1000;this.startPos=x;Ext.dd.DDProxy.prototype.b4StartDrag.call(this,x,y);},handleMouseDown:function(e){ev=Ext.EventObject.setEvent(e);var t=this.fly(ev.getTarget());if(t.hasClass("x-grid-split")){this.cellIndex=this.view.getCellIndex(t.dom);this.split=t.dom;this.cm=this.grid.colModel;if(this.cm.isResizable(this.cellIndex)&&!this.cm.isFixed(this.cellIndex)){Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this,arguments);}}},endDrag:function(e){this.view.headersDisabled=false;var _b=Math.max(this.minX,Ext.lib.Event.getPageX(e));var _c=_b-this.startPos;this.view.onColumnSplitterMoved(this.cellIndex,this.cm.getColumnWidth(this.cellIndex)+_c);},autoOffset:function(){this.setDelta(0,0);}});
+
+Ext.grid.GridDragZone=function(_1,_2){this.view=_1.getView();Ext.grid.GridDragZone.superclass.constructor.call(this,this.view.lockedBody.dom,_2);this.setHandleElId(Ext.id(this.view.lockedBody.dom));this.setOuterHandleElId(Ext.id(this.view.mainBody.dom));this.scroll=false;this.grid=_1;this.ddel=document.createElement("div");this.ddel.className="x-grid-dd-wrap";};Ext.extend(Ext.grid.GridDragZone,Ext.dd.DragZone,{ddGroup:"GridDD",getDragData:function(e){var t=Ext.lib.Event.getTarget(e);var _5=this.view.findRowIndex(t);if(_5!==false){var sm=this.grid.selModel;if(!sm.isSelected(_5)||e.hasModifier()){sm.handleMouseDown(e,t);}return {grid:this.grid,ddel:this.ddel,rowIndex:_5,selections:sm.getSelections()};}return false;},onInitDrag:function(e){var _8=this.dragData;this.ddel.innerHTML=this.grid.getDragDropText();this.proxy.update(this.ddel);},afterRepair:function(){this.dragging=false;},getRepairXY:function(e,_a){return false;},onEndDrag:function(_b,e){},onValidDrop:function(dd,e,id){this.hideProxy();},beforeInvalidDrop:function(e,id){}});
+
+Ext.grid.ColumnModel=function(_1){Ext.grid.ColumnModel.superclass.constructor.call(this);this.config=_1;this.lookup={};for(var i=0,_3=_1.length;i<_3;i++){if(typeof _1[i].dataIndex=="undefined"){_1[i].dataIndex=i;}if(typeof _1[i].renderer=="string"){_1[i].renderer=Ext.util.Format[_1[i].renderer];}if(typeof _1[i].id=="undefined"){_1[i].id=i;}this.lookup[_1[i].id]=_1[i];}this.defaultWidth=100;this.defaultSortable=false;this.events={"widthchange":true,"headerchange":true,"hiddenchange":true,"columnmoved":true,"columnlockchange":true};Ext.grid.ColumnModel.superclass.constructor.call(this);};Ext.extend(Ext.grid.ColumnModel,Ext.util.Observable,{getColumnId:function(_4){return this.config[_4].id;},getColumnById:function(id){return this.lookup[id];},getIndexById:function(id){for(var i=0,_8=this.config.length;i<_8;i++){if(this.config[i].id==id){return i;}}return -1;},moveColumn:function(_9,_a){var c=this.config[_9];this.config.splice(_9,1);this.config.splice(_a,0,c);this.dataMap=null;this.fireEvent("columnmoved",this,_9,_a);},isLocked:function(_c){return this.config[_c].locked===true;},setLocked:function(_d,_e,_f){if(this.isLocked(_d)==_e){return;}this.config[_d].locked=_e;if(!_f){this.fireEvent("columnlockchange",this,_d,_e);}},getTotalLockedWidth:function(){var _10=0;for(var i=0;i<this.config.length;i++){if(this.isLocked(i)&&!this.isHidden(i)){this.totalWidth+=this.getColumnWidth(i);}}return _10;},getLockedCount:function(){for(var i=0,len=this.config.length;i<len;i++){if(!this.isLocked(i)){return i;}}},getColumnCount:function(_14){if(_14==true){var c=0;for(var i=0,len=this.config.length;i<len;i++){if(!this.isHidden(i)){c++;}}return c;}return this.config.length;},isSortable:function(col){if(typeof this.config[col].sortable=="undefined"){return this.defaultSortable;}return this.config[col].sortable;},getRenderer:function(col){if(!this.config[col].renderer){return Ext.grid.ColumnModel.defaultRenderer;}return this.config[col].renderer;},setRenderer:function(col,fn){this.config[col].renderer=fn;},getColumnWidth:function(col){return this.config[col].width||this.defaultWidth;},setColumnWidth:function(col,_1e,_1f){this.config[col].width=_1e;this.totalWidth=null;if(!_1f){this.fireEvent("widthchange",this,col,_1e);}},getTotalWidth:function(_20){if(!this.totalWidth){this.totalWidth=0;for(var i=0,len=this.config.length;i<len;i++){if(_20||!this.isHidden(i)){this.totalWidth+=this.getColumnWidth(i);}}}return this.totalWidth;},getColumnHeader:function(col){return this.config[col].header;},setColumnHeader:function(col,_25){this.config[col].header=_25;this.fireEvent("headerchange",this,col,_25);},getColumnTooltip:function(col){return this.config[col].tooltip;},setColumnTooltip:function(col,_28){this.config[col].tooltip=_28;},getDataIndex:function(col){return this.config[col].dataIndex;},setDataIndex:function(col,_2b){this.config[col].dataIndex=_2b;},findColumnIndex:function(_2c){var c=this.config;for(var i=0,len=c.length;i<len;i++){if(c[i].dataIndex==_2c){return i;}}return -1;},isCellEditable:function(_30,_31){return (this.config[_30].editable||(typeof this.config[_30].editable=="undefined"&&this.config[_30].editor))?true:false;},getCellEditor:function(_32,_33){return this.config[_32].editor;},setEditable:function(col,_35){this.config[col].editable=_35;},isHidden:function(_36){return this.config[_36].hidden;},isFixed:function(_37){return this.config[_37].fixed;},isResizable:function(_38){return this.config[_38].resizable!==false;},setHidden:function(_39,_3a){this.config[_39].hidden=_3a;this.totalWidth=null;this.fireEvent("hiddenchange",this,_39,_3a);},setEditor:function(col,_3c){this.config[col].editor=_3c;}});Ext.grid.ColumnModel.defaultRenderer=function(_3d){if(typeof _3d=="string"&&_3d.length<1){return "&#160;";}return _3d;};Ext.grid.DefaultColumnModel=Ext.grid.ColumnModel;
+
+Ext.grid.AbstractSelectionModel=function(){this.locked=false;Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);};Ext.extend(Ext.grid.AbstractSelectionModel,Ext.util.Observable,{init:function(_1){this.grid=_1;this.initEvents();},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;}});
+
+Ext.grid.RowSelectionModel=function(_1){Ext.apply(this,_1);this.selections=new Ext.util.MixedCollection(false,function(o){return o.id;});this.last=false;this.lastActive=false;this.events={"selectionchange":true,"beforerowselect":true,"rowselect":true,"rowdeselect":true};this.locked=false;};Ext.extend(Ext.grid.RowSelectionModel,Ext.grid.AbstractSelectionModel,{singleSelect:false,initEvents:function(){if(!this.grid.enableDragDrop&&!this.grid.enableDrag){this.grid.on("mousedown",this.handleMouseDown,this);}this.rowNav=new Ext.KeyNav(this.grid.container,{"up":function(e){if(!e.shiftKey){this.selectPrevious(e.shiftKey);}else{if(this.last!==false&&this.lastActive!==false){var _4=this.last;this.selectRange(this.last,this.lastActive-1);this.grid.getView().focusRow(this.lastActive);if(_4!==false){this.last=_4;}}else{this.selectFirstRow();}}},"down":function(e){if(!e.shiftKey){this.selectNext(e.shiftKey);}else{if(this.last!==false&&this.lastActive!==false){var _6=this.last;this.selectRange(this.last,this.lastActive+1);this.grid.getView().focusRow(this.lastActive);if(_6!==false){this.last=_6;}}else{this.selectFirstRow();}}},scope:this});var _7=this.grid.view;_7.on("refresh",this.onRefresh,this);_7.on("rowupdated",this.onRowUpdated,this);_7.on("rowremoved",this.onRemove,this);},onRefresh:function(){var ds=this.grid.dataSource,i,v=this.grid.view;var s=this.selections;s.each(function(r){if((i=ds.indexOfId(r.id))!=-1){v.onRowSelect(i);}else{s.remove(r);}});},onRemove:function(v,_e,r){this.selections.remove(r);},onRowUpdated:function(v,_11,r){if(this.isSelected(r)){v.onRowSelect(_11);}},selectRecords:function(_13,_14){if(!_14){this.clearSelections();}var ds=this.grid.dataSource;for(var i=0,len=_13.length;i<len;i++){this.selectRow(ds.indexOf(_13[i]),true);}},getCount:function(){return this.selections.length;},selectFirstRow:function(){this.selectRow(0);},selectLastRow:function(_18){this.selectRow(this.grid.dataSource.getCount()-1,_18);},selectNext:function(_19){if(this.last!==false&&(this.last+1)<this.grid.dataSource.getCount()){this.selectRow(this.last+1,_19);this.grid.getView().focusRow(this.last);}},selectPrevious:function(_1a){if(this.last){this.selectRow(this.last-1,_1a);this.grid.getView().focusRow(this.last);}},getSelections:function(){return [].concat(this.selections.items);},getSelected:function(){return this.selections.itemAt(0);},clearSelections:function(_1b){if(this.locked){return;}if(_1b!==true){var ds=this.grid.dataSource;var s=this.selections;s.each(function(r){this.deselectRow(ds.indexOfId(r.id));},this);s.clear();}else{this.selections.clear();}this.last=false;},selectAll:function(){if(this.locked){return;}this.selections.clear();for(var i=0,len=this.grid.dataSource.getCount();i<len;i++){this.selectRow(i,true);}},hasSelection:function(){return this.selections.length>0;},isSelected:function(_21){var r=typeof _21=="number"?this.grid.dataSource.getAt(_21):_21;return (r&&this.selections.key(r.id)?true:false);},isIdSelected:function(id){return (this.selections.key(id)?true:false);},handleMouseDown:function(e,t){var _26=this.grid.getView(),_27;if(this.isLocked()||(_27=_26.findRowIndex(t))===false){return;}if(e.shiftKey&&this.last!==false){var _28=this.last;this.selectRange(_28,_27,e.ctrlKey);this.last=_28;_26.focusRow(_27);}else{var _29=this.isSelected(_27);if(e.button!=0&&_29){_26.focusRow(_27);}else{if(e.ctrlKey&&_29){this.deselectRow(_27);}else{this.selectRow(_27,e.button==0&&(e.ctrlKey||e.shiftKey));_26.focusRow(_27);}}}},selectRows:function(_2a,_2b){if(!_2b){this.clearSelections();}for(var i=0,len=_2a.length;i<len;i++){this.selectRow(_2a[i],true);}},selectRange:function(_2e,_2f,_30){if(this.locked){return;}if(!_30){this.clearSelections();}if(_2e<=_2f){for(var i=_2e;i<=_2f;i++){this.selectRow(i,true);}}else{for(var i=_2e;i>=_2f;i--){this.selectRow(i,true);}}},deselectRange:function(_32,_33,_34){if(this.locked){return;}for(var i=_32;i<=_33;i++){this.deselectRow(i,_34);}},selectRow:function(_36,_37,_38){if(this.locked||(_36<0||_36>=this.grid.dataSource.getCount())){return;}if(this.fireEvent("beforerowselect",this,_36,_37)!==false){if(!_37||this.singleSelect){this.clearSelections();}var r=this.grid.dataSource.getAt(_36);this.selections.add(r);this.last=this.lastActive=_36;if(!_38){this.grid.getView().onRowSelect(_36);}this.fireEvent("rowselect",this,_36,r);this.fireEvent("selectionchange",this);}},deselectRow:function(_3a,_3b){if(this.locked){return;}if(this.last==_3a){this.last=false;}if(this.lastActive==_3a){this.lastActive=false;}var r=this.grid.dataSource.getAt(_3a);this.selections.remove(r);if(!_3b){this.grid.getView().onRowDeselect(_3a);}this.fireEvent("rowdeselect",this,_3a);this.fireEvent("selectionchange",this);},restoreLast:function(){if(this._last){this.last=this._last;}},acceptsNav:function(row,col,cm){return !cm.isHidden(col)&&cm.isCellEditable(col,row);},onEditorKey:function(_40,e){var k=e.getKey(),_43,g=this.grid,ed=g.activeEditor;if(k==e.TAB){ed.completeEdit();if(e.shiftKey){_43=g.walkCells(ed.row,ed.col-1,-1,this.acceptsNav,this);}else{_43=g.walkCells(ed.row,ed.col+1,1,this.acceptsNav,this);}e.stopEvent();}else{if(k==e.ENTER&&!e.ctrlKey){ed.completeEdit();if(e.shiftKey){_43=g.walkCells(ed.row-1,ed.col,-1,this.acceptsNav,this);}else{_43=g.walkCells(ed.row+1,ed.col,1,this.acceptsNav,this);}e.stopEvent();}else{if(k==e.ESC){ed.cancelEdit();}}}if(_43){g.startEditing(_43[0],_43[1]);}}});
+
+Ext.grid.CellSelectionModel=function(_1){Ext.apply(this,_1);this.selection=null;this.events={"beforecellselect":true,"cellselect":true,"selectionchange":true};};Ext.extend(Ext.grid.CellSelectionModel,Ext.grid.AbstractSelectionModel,{initEvents:function(){this.grid.on("mousedown",this.handleMouseDown,this);this.grid.container.on(Ext.isIE?"keydown":"keypress",this.handleKeyDown,this);var _2=this.grid.view;_2.on("refresh",this.onViewChange,this);_2.on("rowupdated",this.onRowUpdated,this);_2.on("beforerowremoved",this.clearSelections,this);_2.on("beforerowsinserted",this.clearSelections,this);if(this.grid.isEditor){this.grid.on("beforeedit",this.beforeEdit,this);}},beforeEdit:function(e){this.select(e.row,e.column,false,true,e.record);},onRowUpdated:function(v,_5,r){if(this.selection&&this.selection.record==r){v.onCellSelect(_5,this.selection.cell[1]);}},onViewChange:function(){this.clearSelections(true);},getSelectedCell:function(){return this.selection?this.selection.cell:null;},clearSelections:function(_7){var s=this.selection;if(s){if(_7!==true){this.grid.view.onCellDeselect(s.cell[0],s.cell[1]);}this.selection=null;this.fireEvent("selectionchange",this,null);}},hasSelection:function(){return this.selection?true:false;},handleMouseDown:function(e,t){var v=this.grid.getView();if(this.isLocked()){return;}var _c=v.findRowIndex(t);var _d=v.findCellIndex(t);if(_c!==false&&_d!==false){this.select(_c,_d);}},select:function(_e,_f,_10,_11,r){if(this.fireEvent("beforecellselect",this,_e,_f)!==false){this.clearSelections();r=r||this.grid.dataSource.getAt(_e);this.selection={record:r,cell:[_e,_f]};if(!_10){var v=this.grid.getView();v.onCellSelect(_e,_f);if(_11!==true){v.focusCell(_e,_f);}}this.fireEvent("cellselect",this,_e,_f);this.fireEvent("selectionchange",this,this.selection);}},isSelectable:function(_14,_15,cm){return !cm.isHidden(_15);},handleKeyDown:function(e){if(!e.isNavKeyPress()){return;}var g=this.grid,s=this.selection;if(!s){e.stopEvent();var _1a=g.walkCells(0,0,1,this.isSelectable,this);if(_1a){this.select(_1a[0],_1a[1]);}return;}var sm=this;var _1c=function(row,col,_1f){return g.walkCells(row,col,_1f,sm.isSelectable,sm);};var k=e.getKey(),r=s.cell[0],c=s.cell[1];var _23;switch(k){case e.TAB:if(e.shiftKey){_23=_1c(r,c-1,-1);}else{_23=_1c(r,c+1,1);}break;case e.DOWN:_23=_1c(r+1,c,1);break;case e.UP:_23=_1c(r-1,c,-1);break;case e.RIGHT:_23=_1c(r,c+1,1);break;case e.LEFT:_23=_1c(r,c-1,-1);break;case e.ENTER:if(g.isEditor&&!g.editing){g.startEditing(r,c);e.stopEvent();return;}break;}if(_23){this.select(_23[0],_23[1]);e.stopEvent();}},acceptsNav:function(row,col,cm){return !cm.isHidden(col)&&cm.isCellEditable(col,row);},onEditorKey:function(_27,e){var k=e.getKey(),_2a,g=this.grid,ed=g.activeEditor;if(k==e.TAB){if(e.shiftKey){_2a=g.walkCells(ed.row,ed.col-1,-1,this.acceptsNav,this);}else{_2a=g.walkCells(ed.row,ed.col+1,1,this.acceptsNav,this);}e.stopEvent();}else{if(k==e.ENTER&&!e.ctrlKey){ed.completeEdit();e.stopEvent();}else{if(k==e.ESC){ed.cancelEdit();}}}if(_2a){g.startEditing(_2a[0],_2a[1]);}}});
+
+Ext.grid.EditorGrid=function(_1,_2){Ext.grid.EditorGrid.superclass.constructor.call(this,_1,_2);this.container.addClass("xedit-grid");if(!this.selModel){this.selModel=new Ext.grid.CellSelectionModel();}this.activeEditor=null;Ext.apply(this.events,{"beforeedit":true,"afteredit":true,"validateedit":true});this.on("bodyscroll",this.stopEditing,this);this.on(this.clicksToEdit==1?"cellclick":"celldblclick",this.onCellDblClick,this);};Ext.extend(Ext.grid.EditorGrid,Ext.grid.Grid,{isEditor:true,clicksToEdit:2,trackMouseOver:false,onCellDblClick:function(g,_4,_5){this.startEditing(_4,_5);},onEditComplete:function(ed,_7,_8){this.editing=false;this.activeEditor=null;ed.un("specialkey",this.selModel.onEditorKey,this.selModel);if(String(_7)!=String(_8)){var r=ed.record;var _a=this.colModel.getDataIndex(ed.col);var e={grid:this,record:r,field:_a,originalValue:_8,value:_7,row:ed.row,column:ed.col,cancel:false};if(this.fireEvent("validateedit",e)!==false&&!e.cancel){r.set(_a,_7);delete e.cancel;this.fireEvent("afteredit",e);}}this.view.focusCell(ed.row,ed.col);},startEditing:function(_c,_d){this.stopEditing();if(this.colModel.isCellEditable(_d,_c)){this.view.focusCell(_c,_d);var r=this.dataSource.getAt(_c);var _f=this.colModel.getDataIndex(_d);var e={grid:this,record:r,field:_f,value:r.data[_f],row:_c,column:_d,cancel:false};if(this.fireEvent("beforeedit",e)!==false&&!e.cancel){this.editing=true;(function(){var ed=this.colModel.getCellEditor(_d,_c);ed.row=_c;ed.col=_d;ed.record=r;ed.on("complete",this.onEditComplete,this,{single:true});ed.on("specialkey",this.selModel.onEditorKey,this.selModel);this.activeEditor=ed;var v=r.data[_f];ed.startEdit(this.view.getCell(_c,_d),v);}).defer(50,this);}}},stopEditing:function(){if(this.activeEditor){this.activeEditor.completeEdit();}this.activeEditor=null;}});
+
+Ext.grid.GridEditor=function(_1,_2){Ext.grid.GridEditor.superclass.constructor.call(this,_1,_2);};Ext.extend(Ext.grid.GridEditor,Ext.Editor,{alignment:"tl-tl",autoSize:"width",hideEl:false,cls:"x-small-editor x-grid-editor",shim:false,shadow:"frame"});
+
+Ext.grid.PropertyRecord=Ext.data.Record.create([{name:"name",type:"string"},"value"]);Ext.grid.PropertyStore=function(_1,_2){this.grid=_1;this.store=new Ext.data.Store({recordType:Ext.grid.PropertyRecord});this.store.on("update",this.onUpdate,this);if(_2){this.setSource(_2);}Ext.grid.PropertyStore.superclass.constructor.call(this);};Ext.extend(Ext.grid.PropertyStore,Ext.util.Observable,{setSource:function(o){this.source=o;this.store.removeAll();var _4=[];for(var k in o){if(this.isEditableValue(o[k])){_4.push(new Ext.grid.PropertyRecord({name:k,value:o[k]},k));}}this.store.loadRecords({records:_4},{},true);},onUpdate:function(ds,_7,_8){if(_8==Ext.data.Record.EDIT){var v=_7.data["value"];var _a=_7.modified["value"];if(this.grid.fireEvent("beforepropertychange",this.source,_7.id,v,_a)!==false){this.source[_7.id]=v;_7.commit();this.grid.fireEvent("propertychange",this.source,_7.id,v,_a);}else{_7.reject();}}},getProperty:function(_b){return this.store.getAt(_b);},isEditableValue:function(_c){if(_c&&_c instanceof Date){return true;}else{if(typeof _c=="object"||typeof _c=="function"){return false;}}return true;},setValue:function(_d,_e){this.source[_d]=_e;this.store.getById(_d).set("value",_e);},getSource:function(){return this.source;}});Ext.grid.PropertyColumnModel=function(_f,_10){this.grid=_f;var g=Ext.grid;g.PropertyColumnModel.superclass.constructor.call(this,[{header:this.nameText,sortable:true,dataIndex:"name",id:"name"},{header:this.valueText,resizable:false,dataIndex:"value",id:"value"}]);this.store=_10;this.bselect=Ext.DomHelper.append(document.body,{tag:"select",style:"display:none",cls:"x-grid-editor",children:[{tag:"option",value:"true",html:"true"},{tag:"option",value:"false",html:"false"}]});Ext.id(this.bselect);var f=Ext.form;this.editors={"date":new g.GridEditor(new f.DateField({selectOnFocus:true})),"string":new g.GridEditor(new f.TextField({selectOnFocus:true})),"number":new g.GridEditor(new f.NumberField({selectOnFocus:true,style:"text-align:left;"})),"boolean":new g.GridEditor(new f.Field({el:this.beselect,selectOnFocus:true}))};this.renderCellDelegate=this.renderCell.createDelegate(this);this.renderPropDelegate=this.renderProp.createDelegate(this);};Ext.extend(Ext.grid.PropertyColumnModel,Ext.grid.ColumnModel,{nameText:"Name",valueText:"Value",dateFormat:"m/j/Y",renderDate:function(_13){return _13.dateFormat(this.dateFormat);},renderBool:function(_14){return _14?"true":"false";},isCellEditable:function(_15,_16){return _15==1;},getRenderer:function(col){return col==1?this.renderCellDelegate:this.renderPropDelegate;},renderProp:function(v){return this.getPropertyName(v);},renderCell:function(val){var rv=val;if(val instanceof Date){rv=this.renderDate(val);}else{if(typeof val=="boolean"){rv=this.renderBool(val);}}return Ext.util.Format.htmlEncode(rv);},getPropertyName:function(_1b){var pn=this.grid.propertyNames;return pn&&pn[_1b]?pn[_1b]:_1b;},getCellEditor:function(_1d,_1e){var p=this.store.getProperty(_1e);var n=p.data["name"],val=p.data["value"];if(this.grid.customEditors[n]){return this.grid.customEditors[n];}if(val instanceof Date){return this.editors["date"];}else{if(typeof val=="number"){return this.editors["number"];}else{if(typeof val=="boolean"){return this.editors["boolean"];}else{return this.editors["string"];}}}}});Ext.grid.PropertyGrid=function(_22,_23){_23=_23||{};var _24=new Ext.grid.PropertyStore(this);this.store=_24;var cm=new Ext.grid.PropertyColumnModel(this,_24);_24.store.sort("name","ASC");Ext.grid.PropertyGrid.superclass.constructor.call(this,_22,Ext.apply({ds:_24.store,cm:cm,enableColLock:false,enableColumnMove:false,stripeRows:false,trackMouseOver:false,clicksToEdit:1},_23));this.container.addClass("x-props-grid");this.lastEditRow=null;this.on("columnresize",this.onColumnResize,this);this.addEvents({beforepropertychange:true,propertychange:true});this.customEditors=this.customEditors||{};};Ext.extend(Ext.grid.PropertyGrid,Ext.grid.EditorGrid,{render:function(){Ext.grid.PropertyGrid.superclass.render.call(this);this.autoSize.defer(100,this);},autoSize:function(){Ext.grid.PropertyGrid.superclass.autoSize.call(this);if(this.view){this.view.fitColumns();}},onColumnResize:function(){this.colModel.setColumnWidth(1,this.container.getWidth(true)-this.colModel.getColumnWidth(0));this.autoSize();},setSource:function(_26){this.store.setSource(_26);},getSource:function(){return this.store.getSource();}});
+
+Ext.LoadMask=function(el,_2){this.el=Ext.get(el);Ext.apply(this,_2);if(this.store){this.store.on("beforeload",this.onBeforeLoad,this);this.store.on("load",this.onLoad,this);this.store.on("loadexception",this.onLoad,this);this.removeMask=false;}else{var um=this.el.getUpdateManager();um.showLoadIndicator=false;um.on("beforeupdate",this.onBeforeLoad,this);um.on("update",this.onLoad,this);um.on("failure",this.onLoad,this);this.removeMask=true;}};Ext.LoadMask.prototype={msg:"Loading...",msgCls:"x-mask-loading",disabled:false,disable:function(){this.disabled=true;},enable:function(){this.disabled=false;},onLoad:function(){this.el.unmask(this.removeMask);},onBeforeLoad:function(){if(!this.disabled){this.el.mask(this.msg,this.msgCls);}},destroy:function(){if(this.store){this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("loadexception",this.onLoad,this);}else{var um=this.el.getUpdateManager();um.un("beforeupdate",this.onBeforeLoad,this);um.un("update",this.onLoad,this);um.un("failure",this.onLoad,this);}}};
+
+Ext.debug={init:function(){var CP=Ext.ContentPanel;var bd=Ext.get(document.body);var _3=new Ext.LayoutDialog("x-debug-browser",{autoCreate:true,width:800,height:450,title:"Ext Debug Console &amp; Inspector",proxyDrag:true,shadow:true,center:{alwaysShowTabs:true},constraintoviewport:false});_3.el.swallowEvent("click");var _4=_3.getLayout();_4.beginUpdate();var _5=_4.add("center",new Ext.debug.InnerLayout("x-debug-console",400,{title:"Debug Console"}));var _6=_4.add("center",new Ext.debug.InnerLayout("x-debug-inspector",250,{title:"DOM Inspector"}));var _7=_5.add("east",new CP({autoCreate:{tag:"div",children:[{tag:"div"},{tag:"textarea"}]},fitContainer:true,fitToFrame:true,title:"Script Console",autoScroll:Ext.isGecko,setSize:function(w,h){Ext.ContentPanel.prototype.setSize.call(this,w,h);if(Ext.isGecko&&Ext.isStrict){var s=this.adjustForComponents(w,h);this.resizeEl.setSize(s.width-2,s.height-2);}}}));var _b=_7.el;var _c=_b.child("textarea");_7.resizeEl=_c;var _d=_7.toolbar=new Ext.Toolbar(_b.child("div"));_d.add({text:"Run",handler:function(){var s=_c.dom.value;if(_f.checked){try{var rt=eval(s);Ext.debug.dump(rt===undefined?"(no return)":rt);}catch(e){Ext.debug.log(e.message||e.descript);}}else{var rt=eval(s);Ext.debug.dump(rt===undefined?"(no return)":rt);}}},{text:"Clear",handler:function(){_c.dom.value="";_c.dom.focus();}});var _f=Ext.DomHelper.append(_d.el,{tag:"input",type:"checkbox",checked:"checked"});_f.checked=true;_d.add("-",_f,"Trap Errors");var _11=new Ext.grid.PropertyGrid(bd.createChild(),{nameText:"Style",enableCtxMenu:false,enableColumnResize:false});var _12=_6.add("east",new Ext.GridPanel(_11,{title:"(No element selected)"}));_11.render();_11.getView().mainHd.setDisplayed(false);_5.tbar.add({text:"Clear",handler:function(){Ext.debug.console.jsonData=[];Ext.debug.console.refresh();}});var _13=_6.main.getEl();var tb=_6.tbar;var _15,_16;function inspectListener(e,t){if(!_15.contains(e.getPoint())){findNode(t);}}function stopInspecting(e,t){if(!_15.contains(e.getPoint())){_1b.toggle(false);if(findNode(t)!==false){e.stopEvent();}}}function stopInspectingEsc(e,t){if(e.getKey()==e.ESC){_1b.toggle(false);}}var _1b=tb.addButton({text:"Inspect",enableToggle:true,pressed:false,toggleHandler:function(n,_1f){var d=Ext.get(document);if(_1f){d.on("mouseover",inspectListener,window,{buffer:50});d.on("mousedown",stopInspecting);d.on("keydown",stopInspectingEsc);_15=_3.el.getRegion();_16=true;}else{d.un("mouseover",inspectListener);d.un("mousedown",stopInspecting);d.on("keydown",stopInspectingEsc);_16=false;var n=_21.getSelectionModel().getSelectedNode();if(n&&n.htmlNode){onNodeSelect(_21,n,false);}}}});tb.addSeparator();var _22=tb.addButton({text:"Highlight Selection",enableToggle:true,pressed:false,toggleHandler:function(n,_24){var n=_21.getSelectionModel().getSelectedNode();if(n&&n.htmlNode){n[_24?"frame":"unframe"]();}}});tb.addSeparator();var _25=tb.addButton({text:"Refresh Children",disabled:true,handler:function(){var n=_21.getSelectionModel().getSelectedNode();if(n&&n.reload){n.reload();}}});tb.add("-",{text:"Collapse All",handler:function(){_21.root.collapse(true);}});_4.endUpdate();_4.getRegion("center").showPanel(0);_11.on("propertychange",function(s,_28,_29){var _2a=_11.treeNode;if(_2b){_2a.htmlNode.style[_28]=_29;}else{_2a.htmlNode[_28]=_29;}_2a.refresh(true);});var stb=new Ext.Toolbar(_11.view.getHeaderPanel(true));var _2d=stb.addButton({text:"DOM Attributes",menu:{items:[new Ext.menu.CheckItem({id:"dom",text:"DOM Attributes",checked:true,group:"xdb-styles"}),new Ext.menu.CheckItem({id:"styles",text:"CSS Properties",group:"xdb-styles"})]}});_2d.menu.on("click",function(){_2b=_2d.menu.items.get("styles").checked;_2e[_2b?"show":"hide"]();_2d.setText(_2b?"CSS Properties":"DOM Attributes");var n=_21.getSelectionModel().getSelectedNode();if(n){onNodeSelect(_21,n);}});var _30=stb.addButton({text:"Add",disabled:true,handler:function(){Ext.MessageBox.prompt("Add Property","Property Name:",function(btn,v){var _33=_11.store.store;if(btn=="ok"&&v&&!_33.getById(v)){var r=new Ext.grid.PropertyRecord({name:v,value:""},v);_33.add(r);_11.startEditing(_33.getCount()-1,1);}});}});var _2e=stb.addButton({text:"Computed Styles",hidden:true,pressed:false,enableToggle:true,toggleHandler:function(){var n=_21.getSelectionModel().getSelectedNode();if(n){onNodeSelect(_21,n);}}});var _2b=false,_36;var _37=/^\s*$/;var _38=Ext.util.Format.htmlEncode;var _39=Ext.util.Format.ellipsis;var _3a=/\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;function findNode(n){if(!n||n.nodeType!=1||n==document.body||n==document){return false;}var pn=[n],p=n;while((p=p.parentNode)&&p.nodeType==1&&p.tagName.toUpperCase()!="HTML"){pn.unshift(p);}var cn=_36;for(var i=0,len=pn.length;i<len;i++){cn.expand();cn=cn.findChild("htmlNode",pn[i]);if(!cn){return false;}}cn.select();var a=cn.ui.anchor;_13.dom.scrollTop=Math.max(0,a.offsetTop-10);cn.highlight();return true;}function nodeTitle(n){var s=n.tagName;if(n.id){s+="#"+n.id;}else{if(n.className){s+="."+n.className;}}return s;}function onNodeSelect(t,n,_46){if(_46&&_46.unframe){_46.unframe();}var _47={};if(n&&n.htmlNode){if(_22.pressed){n.frame();}if(_16){return;}_30.enable();_25.setDisabled(n.leaf);var dom=n.htmlNode;_12.setTitle(nodeTitle(dom));if(_2b&&!_2e.pressed){var s=dom.style?dom.style.cssText:"";if(s){var m;while((m=_3a.exec(s))!=null){_47[m[1].toLowerCase()]=m[2];}}}else{if(_2b){var cl=Ext.debug.cssList;var s=dom.style,fly=Ext.fly(dom);if(s){for(var i=0,len=cl.length;i<len;i++){var st=cl[i];var v=s[st]||fly.getStyle(st);if(v!=undefined&&v!==null&&v!==""){_47[st]=v;}}}}else{for(var a in dom){var v=dom[a];if((isNaN(a+10))&&v!=undefined&&v!==null&&v!==""&&!(Ext.isGecko&&a[0]==a[0].toUpperCase())){_47[a]=v;}}}}}else{if(_16){return;}_30.disable();_25.disabled();}_11.setSource(_47);_11.treeNode=n;_11.view.fitColumns();}var _52="^(?:";var eds=_11.colModel.editors;for(var _54 in eds){_52+=eds[_54].id+"|";}Ext.each([_3.shim?_3.shim.id:"noshim",_3.proxyDrag.id,_3.resizer.overlay.id,_3.resizer.proxy.id],function(id){_52+=id+"|";});_52+=_3.el.id;_52+=")$";var _56=new RegExp(_52);var _57=new Ext.tree.TreeLoader();_57.load=function(n,cb){var _5a=n.htmlNode==bd.dom;var cn=n.htmlNode.childNodes;for(var i=0,c;c=cn[i];i++){if(_5a&&_56.test(c.id)){continue;}if(c.nodeType==1){n.appendChild(new Ext.debug.HtmlNode(c));}else{if(c.nodeType==3&&!_37.test(c.nodeValue)){n.appendChild(new Ext.tree.TreeNode({text:"<em>"+_39(_38(String(c.nodeValue)),35)+"</em>",cls:"x-tree-noicon"}));}}}cb();};var _21=new Ext.tree.TreePanel(_13,{enableDD:false,loader:_57,lines:false,rootVisible:false,animate:false,hlColor:"ffff9c"});_21.getSelectionModel().on("selectionchange",onNodeSelect,null,{buffer:250});var _5e=_21.setRootNode(new Ext.tree.TreeNode("Ext"));_36=_5e.appendChild(new Ext.debug.HtmlNode(document.getElementsByTagName("html")[0]));_21.render();Ext.debug.console=new Ext.JsonView(_5.main.getEl(),"<pre><xmp>> {msg}</xmp></pre>");Ext.debug.console.jsonData=[];Ext.debug.dialog=_3;},show:function(){var d=Ext.debug;if(!d.dialog){d.init();}if(!d.dialog.isVisible()){d.dialog.show();}},hide:function(){if(Ext.debug.dialog){Ext.debug.dialog.hide();}},log:function(_60,_61,etc){Ext.debug.show();var m="";for(var i=0,len=arguments.length;i<len;i++){m+=(i==0?"":", ")+arguments[i];}var cn=Ext.debug.console;cn.jsonData.unshift({msg:m});cn.refresh();},logf:function(_67,_68,_69,etc){Ext.debug.log(String.format.apply(String,arguments));},dump:function(o){if(typeof o=="string"||typeof o=="number"||typeof o=="undefined"||o instanceof Date){Ext.debug.log(o);}else{if(!o){Ext.debug.log("null");}else{if(typeof o!="object"){Ext.debug.log("Unknown return type");}else{if(o instanceof Array){Ext.debug.log("["+o.join(",")+"]");}else{var b=["{\n"];for(var key in o){var to=typeof o[key];if(to!="function"&&to!="object"){b.push(String.format("  {0}: {1},\n",key,o[key]));}}var s=b.join("");if(s.length>3){s=s.substr(0,s.length-2);}Ext.debug.log(s+"\n}");}}}}},_timers:{},time:function(_70){_70=_70||"def";Ext._timers[_70]=new Date().getTime();},timeEnd:function(_71,_72){var t=new Date().getTime();_71=_71||"def";var v=String.format("{0} ms",t-Ext._timers[_71]);Ext._timers[_71]=new Date().getTime();if(_72!==false){Ext.debug.log("Timer "+(_71=="def"?v:_71+": "+v));}return v;}};Ext.debug.HtmlNode=function(){var _75=Ext.util.Format.htmlEncode;var _76=Ext.util.Format.ellipsis;var _77=/^\s*$/;var _78=[{n:"id",v:"id"},{n:"className",v:"class"},{n:"name",v:"name"},{n:"type",v:"type"},{n:"src",v:"src"},{n:"href",v:"href"}];function hasChild(n){for(var i=0,c;c=n.childNodes[i];i++){if(c.nodeType==1){return true;}}return false;}function renderNode(n,_7d){var tag=n.tagName.toLowerCase();var s="&lt;"+tag;for(var i=0,len=_78.length;i<len;i++){var a=_78[i];var v=n[a.n];if(v&&!_77.test(v)){s+=" "+a.v+"=&quot;<i>"+_75(v)+"</i>&quot;";}}var _84=n.style?n.style.cssText:"";if(_84){s+=" style=&quot;<i>"+_75(_84.toLowerCase())+"</i>&quot;";}if(_7d&&n.childNodes.length>0){s+="&gt;<em>"+_76(_75(String(n.innerHTML)),35)+"</em>&lt;/"+tag+"&gt;";}else{if(_7d){s+=" /&gt;";}else{s+="&gt;";}}return s;}var _85=function(n){var _87=!hasChild(n);this.htmlNode=n;this.tagName=n.tagName.toLowerCase();var _88={text:renderNode(n,_87),leaf:_87,cls:"x-tree-noicon"};_85.superclass.constructor.call(this,_88);this.attributes.htmlNode=n;if(!_87){this.on("expand",this.onExpand,this);this.on("collapse",this.onCollapse,this);}};Ext.extend(_85,Ext.tree.AsyncTreeNode,{cls:"x-tree-noicon",preventHScroll:true,refresh:function(_89){var _8a=!hasChild(this.htmlNode);this.setText(renderNode(this.htmlNode,_8a));if(_89){Ext.fly(this.ui.textNode).highlight();}},onExpand:function(){if(!this.closeNode&&this.parentNode){this.closeNode=this.parentNode.insertBefore(new Ext.tree.TreeNode({text:"&lt;/"+this.tagName+"&gt;",cls:"x-tree-noicon"}),this.nextSibling);}else{if(this.closeNode){this.closeNode.ui.show();}}},onCollapse:function(){if(this.closeNode){this.closeNode.ui.hide();}},render:function(_8b){_85.superclass.render.call(this,_8b);},highlightNode:function(){},highlight:function(){},frame:function(){this.htmlNode.style.border="1px solid #0000ff";},unframe:function(){this.htmlNode.style.border="";}});return _85;}();Ext.debug.InnerLayout=function(id,w,cfg){var el=Ext.DomHelper.append(document.body,{id:id});var _90=new Ext.BorderLayout(el,{north:{initialSize:28},center:{titlebar:false},east:{split:true,initialSize:w,titlebar:true}});Ext.debug.InnerLayout.superclass.constructor.call(this,_90,cfg);_90.beginUpdate();var _91=_90.add("north",new Ext.ContentPanel({autoCreate:true,fitToFrame:true}));this.main=_90.add("center",new Ext.ContentPanel({autoCreate:true,fitToFrame:true,autoScroll:true}));this.tbar=new Ext.Toolbar(_91.el);var _92=_91.resizeEl=_91.el.child("div.x-toolbar");_92.setStyle("border-bottom","0 none");_90.endUpdate(true);};Ext.extend(Ext.debug.InnerLayout,Ext.NestedLayoutPanel,{add:function(){return this.layout.add.apply(this.layout,arguments);}});Ext.debug.cssList=["background-color","border","border-color","border-spacing","border-style","border-top","border-right","border-bottom","border-left","border-top-color","border-right-color","border-bottom-color","border-left-color","border-top-width","border-right-width","border-bottom-width","border-left-width","border-width","bottom","color","font-size","font-size-adjust","font-stretch","font-style","height","left","letter-spacing","line-height","margin","margin-top","margin-right","margin-bottom","margin-left","marker-offset","max-height","max-width","min-height","min-width","orphans","outline","outline-color","outline-style","outline-width","overflow","padding","padding-top","padding-right","padding-bottom","padding-left","quotes","right","size","text-indent","top","width","word-spacing","z-index","opacity","outline-offset"];if(typeof console=="undefined"){console=Ext.debug;}Ext.EventManager.on(window,"load",function(){Ext.get(document).on("keydown",function(e){if(e.ctrlKey&&e.shiftKey&&e.getKey()==e.HOME){Ext.debug.show();}});});Ext.print=Ext.log=Ext.debug.log;Ext.printf=Ext.logf=Ext.debug.logf;Ext.dump=Ext.debug.dump;Ext.timer=Ext.debug.time;Ext.timerEnd=Ext.debug.timeEnd;
+

Added: jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/ext-config.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/ExtJS/share/web/static/js/extjs/ext-config.js	Mon May  7 16:28:32 2007
@@ -0,0 +1 @@
+Ext.BLANK_IMAGE_URL = "/static/images/extjs/default/s.gif"; 

Added: jifty/branches/virtual-models/plugins/WikiToolbar/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WikiToolbar/Makefile.PL	Mon May  7 16:28:32 2007
@@ -0,0 +1,8 @@
+use inc::Module::Install;
+name('Jifty-Plugin-WikiToolbar');
+version('0.01');
+requires('Jifty' => '0.70416');
+
+install_share;
+
+WriteAll;

Added: jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,38 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::WikiToolbar;
+use base qw/Jifty::Plugin/;
+
+=head1 SYNOPSIS
+
+In etc/config.yml
+
+   Plugins:
+     - WikiToolbar: {}
+
+In your Model instead of 
+
+   render_as 'textarea';
+
+use
+
+  render_as 'Jifty::Plugin::WikiToolbar::Textarea';
+
+To custom the toolbar, copy wikitoolbar.js in your application, at the end of the file put your changes with addButton function.
+
+=head1 DESCRIPTION
+
+Add a toolbar to your textarea field. Default toolbar provide markdown markup syntax. http://daringfireball.net/projects/markdown/
+
+=cut
+
+sub init {
+    my $self = shift;
+    Jifty->web->javascript_libs([
+    @{ Jifty->web->javascript_libs },
+    "wikitoolbar.js",
+    ]);
+}
+
+1;

Added: jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::WikiToolbar::Dispatcher;
+use Jifty::Dispatcher -base;
+
+# Put any plugin-specific dispatcher rules here.
+
+1;

Added: jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Textarea.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WikiToolbar/lib/Jifty/Plugin/WikiToolbar/Textarea.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,24 @@
+package Jifty::Plugin::WikiToolbar::Textarea;
+use base qw(Jifty::Web::Form::Field::Textarea);
+
+sub rows { 30 };
+
+sub render_widget {
+    my $self  = shift;
+    my $field;
+    $field .= qq!<div id='toolbar'></div>!;
+    $field .= qq!<textarea!;
+    $field .= qq! name="@{[ $self->input_name ]}"!;
+    $field .= qq! id="@{[ $self->element_id ]}"!;
+    $field .= qq! rows="@{[$self->rows || 5 ]}"!;
+    $field .= qq! cols="@{[$self->cols || 60]}"!;
+    $field .= $self->_widget_class;
+    $field .= qq! >!;
+    $field .= Jifty->web->escape($self->current_value) if $self->current_value;
+	$field .= qq!</textarea>\n!;
+    Jifty->web->out($field);
+    '';
+}
+
+
+1;

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/bold.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/box.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/center.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/code.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/code1.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/empty.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/h1.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/h2.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/h3.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/italic.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/link.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/linkextern.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/new.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/ol.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/red.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/strike.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/tab.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/ul.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/img/wt/underline.png
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/js/wikitoolbar.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WikiToolbar/share/web/static/js/wikitoolbar.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,137 @@
+// Wikipedia JavaScript toolbar functions
+
+mwEditButtons = [];
+
+// this function generates the actual toolbar buttons with localized text
+// we use it to avoid creating the toolbar where javascript is not enabled
+function addButton(imageFile, speedTip, tagOpen, tagClose, sampleText) {
+	mwEditButtons[mwEditButtons.length] =
+		{"imageFile": imageFile,
+		 "speedTip": speedTip,
+		 "tagOpen": tagOpen,
+		 "tagClose": tagClose,
+		 "sampleText": sampleText};
+}
+
+// this function generates the actual toolbar buttons with localized text
+// we use it to avoid creating the toolbar where javascript is not enabled
+function mwInsertEditButton(parent, item) {
+    if (typeof item.imageFile == 'undefined') {
+        return;}
+	var image = document.createElement("img");
+	image.width = 16;
+	image.height = 16;
+	image.src = item.imageFile;
+	image.border = 0;
+	image.alt = item.speedTip;
+	image.title = item.speedTip;
+	image.style.cursor = "pointer";
+	image.onclick = function() {
+		insertTags(item.tagOpen, item.tagClose, item.sampleText);
+		return false;
+	}
+	parent.appendChild(image);
+}
+
+// apply tagOpen/tagClose to selection in textarea,
+// use sampleText instead of selection if there is none
+// copied and adapted from phpBB
+function insertTags(tagOpen, tagClose, sampleText) {
+
+   // var txtarea = document.getElementsByTagName('TEXTAREA')[0];
+    // TODO: need a better way to manage multi textarea
+    var txtarea;
+    var txtareas = document.getElementsByTagName('TEXTAREA');
+    for (i = 0; i < txtareas.length; i++) {
+        var textbox = txtareas[i];
+        if( textbox.selectionStart ) {
+            txtarea = textbox;
+        };
+    }
+
+    if (typeof txtarea == 'undefined') {
+        txtarea = document.getElementsByTagName('TEXTAREA')[0];
+    }
+
+	// IE
+	if (document.selection && !is_gecko) {
+		var theSelection = document.selection.createRange().text;
+		if (!theSelection)
+			theSelection=sampleText;
+		txtarea.focus();
+		if (theSelection.charAt(theSelection.length - 1) == " ") { // exclude ending space char, if any
+			theSelection = theSelection.substring(0, theSelection.length - 1);
+			document.selection.createRange().text = tagOpen + theSelection + tagClose + " ";
+		} else {
+			document.selection.createRange().text = tagOpen + theSelection + tagClose;
+		}
+
+	// Mozilla
+	} else if(txtarea.selectionStart || txtarea.selectionStart == '0') {
+		var replaced = false;
+		var startPos = txtarea.selectionStart;
+		var endPos = txtarea.selectionEnd;
+		if (endPos-startPos)
+			replaced = true;
+		var scrollTop = txtarea.scrollTop;
+		var myText = (txtarea.value).substring(startPos, endPos);
+		if (!myText)
+			myText=sampleText;
+		if (myText.charAt(myText.length - 1) == " ") { // exclude ending space char, if any
+			subst = tagOpen + myText.substring(0, (myText.length - 1)) + tagClose + " ";
+		} else {
+			subst = tagOpen + myText + tagClose;
+		}
+		txtarea.value = txtarea.value.substring(0, startPos) + subst +
+			txtarea.value.substring(endPos, txtarea.value.length);
+		txtarea.focus();
+		//set new selection
+		if (replaced) {
+			var cPos = startPos+(tagOpen.length+myText.length+tagClose.length);
+			txtarea.selectionStart = cPos;
+			txtarea.selectionEnd = cPos;
+		} else {
+			txtarea.selectionStart = startPos+tagOpen.length;
+			txtarea.selectionEnd = startPos+tagOpen.length+myText.length;
+		}
+		txtarea.scrollTop = scrollTop;
+
+	// All other browsers get no toolbar.
+	// There was previously support for a crippled "help"
+	// bar, but that caused more problems than it solved.
+	}
+	// reposition cursor if possible
+	if (txtarea.createTextRange)
+		txtarea.caretPos = document.selection.createRange().duplicate();
+}
+
+
+
+var myrules = {
+        '#toolbar' : function(e){
+			mwEditButtons = [];
+// CUSTOM your toolbar HERE
+// addButton : image, help text, first tag before selected text, last tag, default text if nothing is selected
+addButton('/static/img/wt/bold.png','Bold text','\*\*','\*\*','Bold text');
+addButton('/static/img/wt/italic.png','Italic text','\_','\_','Italic text');
+  addButton('/static/img/wt/empty.png','','','','');
+addButton('/static/img/wt/h1.png','Title','','\n=======\n','Title');
+addButton('/static/img/wt/h2.png','Sub title','','\n-------\n','Sub title');
+addButton('/static/img/wt/h3.png','Sub sub title','### ',' ###\n','Sub sub title');
+  addButton('/static/img/wt/empty.png','','','','');
+addButton('/static/img/wt/link.png','Link','[','](http://...... )','Text');
+addButton('/static/img/wt/linkextern.png','URL','<','>','http://.....');
+  addButton('/static/img/wt/empty.png','','','','');
+addButton('/static/img/wt/ul.png','List','\n- element 1\n- element 2\n- element 3\n\n ','','');
+addButton('/static/img/wt/ol.png','Ordered list','\n1. element 1\n1. element 2\n1. element 3\n\n ','','');
+// END
+
+	for(i=0;i<mwEditButtons.length;i++) {
+		mwInsertEditButton(e, mwEditButtons[i]);
+	}
+
+        }
+    };
+    
+Behaviour.register(myrules);
+

Added: jifty/branches/virtual-models/plugins/WyzzEditor/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/Makefile.PL	Mon May  7 16:28:32 2007
@@ -0,0 +1,8 @@
+use inc::Module::Install;
+name('Jifty-Plugin-WyzzEditor');
+version('0.01');
+requires('Jifty' => '0.70416');
+
+install_share;
+
+WriteAll;

Added: jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,49 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::WyzzEditor;
+use base qw/Jifty::Plugin/;
+
+=head1 SYNOPSIS
+
+In etc/config.yml
+
+   Plugins:
+     - WyzzEditor: {}
+
+In your Model instead of 
+
+   render_as 'teaxterea';
+
+use
+
+  render_as 'Jifty::Plugin::WyzzEditor::Textarea';
+
+
+In your View 
+
+  Jifty->web->link( 
+    label   => _("Save"), 
+    onclick => [
+      { beforeclick =>
+          "updateTextArea('".$action->form_field('myfield')->element_id."');" },
+      { args => .... }
+    ]
+  );
+
+=head1 DESCRIPTION
+
+Wyzz, simple WYSIWYG online editor usable in fragments
+
+=cut
+
+
+sub init {
+	my $self = shift;
+	Jifty->web->javascript_libs([
+	@{ Jifty->web->javascript_libs },
+	"wyzz.js",
+	]);
+}
+
+1;

Added: jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::WyzzEditor::Dispatcher;
+use Jifty::Dispatcher -base;
+
+# Put any plugin-specific dispatcher rules here.
+
+1;

Added: jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/Textarea.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/lib/Jifty/Plugin/WyzzEditor/Textarea.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,25 @@
+package Jifty::Plugin::WyzzEditor::Textarea;
+use base qw(Jifty::Web::Form::Field::Textarea);
+
+sub render_widget {
+    my $self  = shift;
+    my $field;
+    $field .= qq!<textarea!;
+    $field .= qq! name="@{[ $self->input_name ]}"!;
+    $field .= qq! id="@{[ $self->element_id ]}"!;
+    $field .= qq! rows="@{[$self->rows || 5 ]}"!;
+    $field .= qq! cols="@{[$self->cols || 60]}"!;
+    $field .= $self->_widget_class;
+    $field .= qq! >!;
+    $field .= Jifty->web->escape($self->current_value) if $self->current_value;
+    $field .= qq!</textarea>\n!;
+	$field .= qq!<script type="text/javascript">\n!;
+	$field .= qq! make_wyzz('@{[ $self->element_id ]}');\n!; 
+    $field .= qq!</script>\n!; 
+
+    Jifty->web->out($field);
+    '';
+}
+
+
+1;

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/backcolor.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/bold.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/close.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/copy.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/cut.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/downsize.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/font.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/forecolor.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/headers.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/help.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/htmlmode.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/indent.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/inserthorizontalrule.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/insertimage.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/insertorderedlist.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/insertunorderedlist.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/italic.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifycenter.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifyfull.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifyleft.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/justifyright.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/link.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/outdent.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/paste.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/redo.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/removeformat.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/specialchar.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/strikethrough.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/subscript.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/superscript.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/underline.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/undo.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/upsize.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/img/wyzzicons/wyzzicon.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/js/wyzz.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/js/wyzz.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,732 @@
+
+// WYZZ Copyright (c) 2007 The Mouse Whisperer
+// Contains code Copyright (c) 2006 openWebWare.com
+// This copyright notice MUST stay intact for use.
+//
+// An open source WYSIWYG editor for use in web based applications.
+// For full source code and docs, visit http://www.wyzz.info
+//
+// This library is free software; you can redistribute it and/or modify 
+// it under the terms of the GNU Lesser General Public License as published 
+// by the Free Software Foundation; either version 2.1 of the License, or 
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but 
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
+// License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License along 
+// with this library; if not, write to the Free Software Foundation, Inc., 59 
+// Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+/****************************************************************************************/
+// MODIFY THE PARAMETERS IN THE FOLLOWING SECTION TO SUIT YOUR APPLICATION ///////////////
+
+// Editor Width and Height
+wyzzW = 600;
+wyzzH = 200;
+
+// Number of toolbars - must be either 1 or 2
+// If set to 1, the first tooolbar (defined in array buttonName below) will be ignored
+toolbarCount = 2;
+
+// Edit region stylesheet
+editstyle = '/static/wyzzstyles/editarea.css';
+
+// Do we want to try to clean the code to emulate xhtml? 1=Yes, 0=No
+xhtml_out = 1;
+
+// Style Sheet
+document.write('<link rel="stylesheet" type="text/css" href="/static/wyzzstyles/style.css">\n');
+
+// TOOLBARS ARRAYS
+// Order of available commands in toolbar
+// Remove from this any buttons not required in your application
+var buttonName = new Array("font","headers","separator","bold","italic","underline","strikethrough","separator","cut","copy","paste","separator","subscript","superscript","separator","justifyleft","justifycenter","justifyright","justifyfull","indent","outdent","separator","insertunorderedlist","insertorderedlist","separator","link","insertimage","separator","undo","redo");
+
+// Order of available commands in toolbar2
+// Remove from this any buttons not required in your application
+var buttonName2 = new Array("specialchar","separator","forecolor","backcolor","separator","inserthorizontalrule","separator","removeformat","separator","upsize","downsize","separator","htmlmode","separator","help");
+
+var myFonts = new Array("Andale Mono","Georgia","Verdana","Arial","Arial Black","impact","Times New Roman","Courier New","Comic Sans MS","Helvetica","Trebuchet MS","Tahoma");
+
+var specialChars = new Array("&copy;","&reg;","&#153;","&agrave;","&aacute;","&ccedil;","&egrave;","&eacute;","&euml;","&igrave;","&iacute;","&ntilde;","&ograve;","&oacute;","&ouml;","&ugrave;","&uacute;","&uuml;","&pound;","&cent;","&yen;","&euro;","&#147;","&#148;","&laquo;","&raquo;","&#149;","&#151;","&#133;","&para;","&#8224;","&#8225;","&times;","&divide;","&deg;","&plusmn;","&frac14;","&frac12;","&frac34;","&not;","&lt;","&gt;","&Delta;","&lambda;","&Phi;","&Psi;","&Sigma;","&int;","&alpha;","&beta;","&Omega;","&mu;","&pi;","&theta;","&harr;","&infin;","&radic;","&asymp;","&ne;","&equiv;","&le;","&ge;","&iexcl;","&iquest;","&spades;","&clubs;","&hearts;","&diams;");
+
+// DON'T MODIFY BEYOND THIS LINE unless you know what you are doing //////////////
+/********************************************************************************/
+
+version = "0.62"; // Please leave this
+
+var Headers = new Array("P","PRE","H1","H2","H3","H4","H5","H6");
+
+// Mode wysiwyg = 1 or sourcecode = 0
+mode = 1;
+
+// Get browser
+browserName = navigator.appName;
+
+nlBefore = new Array("div","p","li","h1","h2","h3","h4","h5","h6","hr","ul","ol");
+
+function h2x(node,inPre) { // we will pass the node containing the Wyzz-generated html
+  var xout = '';
+  var i;
+  var j;
+  // for each child of the node
+  for(i=0;i<node.childNodes.length;i++) {
+  if(node.childNodes[i].parentNode && String(node.tagName).toLowerCase() != String(node.childNodes[i].parentNode.tagName).toLowerCase()) continue;
+  // alert('Nodes: '+ node.childNodes.length);
+  switch(node.childNodes[i].nodeType) {
+    case 1: { // for element nodes
+      // get tag name
+      var tagname = String(node.childNodes[i].tagName).toLowerCase();
+      if(tagname == '') break;
+      if((indexOf(nlBefore,tagname)!=-1)&&(!inPre)) { // this tag needs line break before it
+        xout += '\n';
+      }
+      xout += '<' + tagname;
+      var atts = node.childNodes[i].attributes;
+      var attvalue;
+      for(j=0;j<atts.length;j++) { // for each attribute
+        var attname = atts[j].nodeName.toLowerCase();
+        if(!atts[j].specified) continue;
+        var validatt = true;
+        switch(attname) {
+          case "style": attvalue = node.childNodes[i].style.cssText; break;
+          case "class": attvalue = node.childNodes[i].className; break;
+          case "name": attvalue = node.childNodes[i].name; break;
+          default:
+            try {
+              attvalue = node.childNodes[i].getAttribute(attname,2);
+            } catch(e) {
+              validatt = false;
+            }
+          }
+          if(validatt) {
+            if(!(tagname=='li' && attname == 'value')) {
+              xout += ' '+attname + '="' + fixatt(attvalue) + '"';
+            }
+          }
+        }
+        if(tagname == 'img' && attname == 'alt') {
+          xout += ' alt=""';
+        }
+        if(node.childNodes[i].canHaveChildren||node.childNodes[i].hasChildNodes()) {
+          xout += '>';
+          xout += h2x(node.childNodes[i],tagname=='pre'?true:false);
+          xout += '</' + tagname + '>';
+        } else {
+          if(tagname == 'style'||tagname == 'title'||tagname=='script'||tagname=='textarea'||tagname=='a') {
+            xout += '>';
+            var innertext;
+            if(tagname=='script') {
+              innertext = node.childNodes[i].text;
+            } else {
+              innertext = node.childNodes[i].innerHTML;
+            }
+            if(tagname=='style') {
+              innertext = String(innertext).replace(/[\n]+/g,'\n');
+            }
+            xout += innertext + '</' + tagname + '>';
+          } else {
+            xout += '/>';
+          }
+        }
+      break;
+    }
+//    else if(node.childNodes[i].nodeType == 2) { // for attribute nodes
+    
+//    }
+    case 3: { // for text nodes
+      if(!inPre) { // don't change inside a <pre> tag
+        if(node.childNodes[i] != '\n') {
+          xout += fixents(fixtext(node.childNodes[i].nodeValue));
+        }
+      } else {
+          xout += node.childNodes[i].nodeValue;     
+        break;
+      }
+    }
+    default: 
+      break;
+    }
+  }
+  return xout;
+}
+
+function fixents(text) {
+  var i;
+  var ents = {8364 : "euro",402  : "fnof",8240 : "permil",352  : "Scaron",338  : "OElig",381  : "#381",8482 : "trade",353  : "scaron",339  : "oelig",382  : "#382",376  : "Yuml",162  : "cent",163  : "pound",164  : "curren",165  : "yen",166  : "brvbar",167  : "sect",168  : "uml",169  : "copy",170  : "ordf",171  : "laquo",172  : "not",173  : "shy",174  : "reg",175  : "macr",176  : "deg",177  : "plusmn",178  : "sup2",179  : "sup3",180  : "acute",181  : "micro",182  : "para",183  : "middot",184  : "cedil",185  : "sup1",186  : "ordm",187  : "raquo",188  : "frac14",189  : "frac12",190  : "frac34",191  : "iquest",192  : "Agrave",193  : "Aacute",194  : "Acirc",195  : "Atilde",196  : "Auml",197  : "Aring",198  : "AElig",199  : "Ccedil",200  : "Egrave",201  : "Eacute",202  : "Ecirc",203  : "Euml",204  : "Igrave",205  : "Iacute",206  : "Icirc",207  : "Iuml",208  : "ETH",209  : "Ntilde",210  : "Ograve",211  : "Oacute",212  : "Ocirc",213  : "Otilde",214  : "Ouml",215  : "times",216  : "Oslash",217  : "Ugrave",218  : "Uacute",219  : "Ucirc",220  : "Uuml",221  : "Yacute",222  : "THORN",223  : "szlig",224  : "agrave",225  : "aacute",226  : "acirc",227  : "atilde",228  : "auml",229  : "aring",230  : "aelig",231  : "ccedil",232  : "egrave",233  : "eacute",234  : "ecirc",235  : "euml",236  : "igrave",237  : "iacute",238  : "icirc",239  : "iuml",240  : "eth",241  : "ntilde",242  : "ograve",243  : "oacute",244  : "ocirc",245  : "otilde",246  : "ouml",247  : "divide",248  : "oslash",249  : "ugrave",250  : "uacute",251  : "ucirc",252  : "uuml",253  : "yacute",254  : "thorn",255  : "yuml",913  : "Alpha",914  : "Beta",915  : "Gamma",916  : "Delta",917  : "Epsilon",918  : "Zeta",919  : "Eta",920  : "Theta",921  : "Iota",922  : "Kappa",923  : "Lambda",924  : "Mu",925  : "Nu",926  : "Xi",927  : "Omicron",928  : "Pi",929  : "Rho",	931  : "Sigma",932  : "Tau",933  : "Upsilon",934  : "Phi",935  : "Chi",936  : "Psi",937  : "Omega",8756 : "there4",8869 : "perp",945  : "alpha",946  : "beta",947  : "gamma",948  : "delta",949  : "epsilon",950  : "zeta",951  : "eta",952  : "theta",953  : "iota",954  : "kappa",955  : "lambda",956  : "mu",957  : "nu",968  : "xi",969  : "omicron",960  : "pi",961  : "rho",962  : "sigmaf",963  : "sigma",964  : "tau",965  : "upsilon",966  : "phi",967  : "chi",968  : "psi",969  : "omega",8254 : "oline",8804 : "le",8260 : "frasl",8734 : "infin",8747 : "int",9827 : "clubs",9830 : "diams",9829 : "hearts",9824 : "spades",8596 : "harr",8592 : "larr",8594 : "rarr",8593 : "uarr",8595 : "darr",8220 : "ldquo",8221 : "rdquo",8222 : "bdquo",8805 : "ge",8733 : "prop",8706 : "part",8226 : "bull",8800 : "ne",8801 : "equiv",8776 : "asymp",8230 : "hellip",8212 : "mdash",8745 : "cap",8746 : "cup",8835 : "sup",8839 : "supe",8834 : "sub",8838 : "sube",8712 : "isin",8715 : "ni",8736 : "ang",8711 : "nabla",8719 : "prod",8730 : "radic",8743 : "and",8744 : "or",8660 : "hArr",8658 : "rArr",9674 : "loz",8721 : "sum",8704 : "forall",8707 : "exist",8216 : "lsquo",8217 : "rsquo",161  : "iexcl",977  : "thetasym",978  : "upsih",982  : "piv",8242 : "prime",8243 : "Prime",8472 : "weierp",8465 : "image",8476 : "real",8501 : "alefsym",8629 : "crarr",8656 : "lArr",8657 : "uArr",8659 : "dArr",8709 : "empty",8713 : "notin",8727 : "lowast",8764 : "sim",8773 : "cong",8836 : "nsub",8853 : "oplus",8855 : "otimes",8901 : "sdot",8968 : "lceil",8969 : "rceil",8970 : "lfloor",8971 : "rfloor",9001 : "lang",9002 : "rang",710  : "circ",732  : "tilde",8194 : "ensp",8195 : "emsp",8201 : "thinsp",8204 : "zwnj",8205 : "zwj",8206 : "lrm",8207 : "rlm",8211 : "ndash",8218 : "sbquo",8224 : "dagger",8225 : "Dagger",8249 : "lsaquo",8250 : "rsaquo"};
+
+  var new_text = '';
+
+  var temp = new RegExp();
+  temp.compile("[a]|[^a]", "g");
+
+  var parts = text.match(temp);
+
+  if (!parts) return text;
+  for (i=0; i<parts.length; i++) {
+    var c_code = parseInt(parts[i].charCodeAt());
+    if (ents[c_code]) {
+      new_text += "&"+ents[c_code]+";";
+    } else new_text += parts[i];
+  }
+  return new_text;
+}
+
+function fixtext(text) {
+  var temptext = String(text).replace(/\&lt;/g,"#h2x_lt").replace(/\&gt;/g,"#h2x_gt");
+  temptext = temptext.replace(/\n{2,}/g,"\n").replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\u00A0/g,"&nbsp;");
+  return temptext.replace(/#h2x_lt/g,"&alt;").replace(/#h2x_gt/g,"&gt;");
+}
+
+function fixatt(text) {
+  var temptext = String(text).replace(/\&lt;/g,"#h2x_lt").replace(/\&gt;/g,"#h2x_gt");
+  temptext = temptext.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;");
+  return temptext.replace(/#h2x_lt/g,"&alt;").replace(/#h2x_gt/g,"&gt;");  
+}
+
+function indexOf(thisarray, value)
+{
+    var i;
+    for (i=0; i < thisarray.length; i++) {
+        if (thisarray[i] == value) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+// Color picker - here we make an array of all websafe colors
+// If you want to limit the colors available to users (e.g. to fit in with
+// a site design) then use a restricted array of colors
+// e.g. var buttonName = new Array("336699","66abff", .... etc
+var buttonColors = new Array(216);
+
+// Colors - replace this function with your own if you have special requirements for colors
+function getColorArray() {
+// Color code table 
+c = new Array('00', '33', '66', '99', 'cc', 'ff'); 
+var count = 0;
+// Iterate red
+for (r = 0; r < 6; r++) 
+  { 
+    // Iterate green
+    for (g = 0; g < 6; g++) 
+      { 
+        // Iterate blue
+        for (b = 0; b < 6; b++) 
+          { 
+            // Get RGB color
+            buttonColors[count] = c[r] + c[g] + c[b]; 
+            count++;
+          } 
+      } 
+  }
+}
+
+getColorArray();
+	
+/* Emulates insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement() three functions 
+so they work with Netscape 6/Mozilla - By Thor Larholm me at jscript.dk */
+if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement) {
+  HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode) {
+  switch (where) {
+    case 'beforeBegin':
+      this.parentNode.insertBefore(parsedNode,this)
+      break;
+    case 'afterBegin':
+      this.insertBefore(parsedNode,this.firstChild);
+      break;
+    case 'beforeEnd':
+      this.appendChild(parsedNode);
+      break;
+    case 'afterEnd':
+      if (this.nextSibling) {
+        this.parentNode.insertBefore(parsedNode,this.nextSibling);
+      } else {
+        this.parentNode.appendChild(parsedNode);
+        break;
+      }
+    }
+  }
+
+  HTMLElement.prototype.insertAdjacentHTML = function (where,htmlStr) {
+    var r = this.ownerDocument.createRange();
+    r.setStartBefore(this);
+    var parsedHTML = r.createContextualFragment(htmlStr);
+    this.insertAdjacentElement(where,parsedHTML)
+  }
+
+  HTMLElement.prototype.insertAdjacentText = function (where,txtStr) {
+    var parsedText = document.createTextNode(txtStr)
+    this.insertAdjacentElement(where,parsedText)
+  }
+}
+
+function closeColorPicker(thisid) {
+  document.getElementById(thisid).style.display = "none";
+}
+
+// the hyperlink dialog
+function insertLink(n) {
+  var newWindow = '';
+  var linkurl = '';
+  var linktitle = '';
+  var targetText = grabSelectedText(n);
+  var linkurl = prompt('Enter the target URL of the link:');
+  var linktitle = prompt('Please give a title for the link:');
+  var openNew = confirm('Should this link open in a new window?\n\nOK = Open in NEW Window\nCancel = Open in THIS window');
+  if(openNew)     {
+    newWindow = "blank";
+  } else {
+    newWindow = "self";
+  }    
+  if(newWindow==''||linkurl==''||linktitle=='') {
+    alert('Please enter all the required information.');
+    insertLink(n);
+  } else {
+    var hyperLink = '<a href="' + linkurl + '" target="_' + newWindow + '" title="' + linktitle + '">' + targetText + '</a>';
+    insertHTML(hyperLink, n);
+  }
+}
+  
+function insertImage(n) {
+  var imgurl = prompt('Enter the target URL of the image:');
+  var imgtitle = prompt('Please give a title for the link:');
+  var theImage = '<img src="' + imgurl + '" title="' + imgtitle + '" />';
+  insertHTML(theImage, n);  }
+
+function make_wyzz(textareaID) {
+  
+  // Hide the textarea 
+  document.getElementById(textareaID).style.display = 'none'; 
+	
+  // get textareaID
+  var n = textareaID;
+	
+  // Toolbars width is 2 pixels wider than the editor
+  toolbarWidth = parseFloat(wyzzW) + 2;
+
+  var toolbar = '';
+  
+  // We only generate toolbar 1 if toolbarCount is set to 2
+  if(toolbarCount == 2) {
+    // Generate WYSIWYG toolbar
+    toolbar =  '<table cellpadding="0" cellspacing="0" border="0" class="toolbar" style="width:' + toolbarWidth + 'px;"><tr>';
+  
+    // Output buttons for toolbar
+    var colNumbers = 0;
+    for (btn in buttonName) {
+     if ( colNumbers < buttonName.length ) {
+      colNumbers ++;
+      if(buttonName[btn] == "separator") {
+        toolbar += '<td class="separator">&nbsp;</td>';
+        } else {
+        toolbar += '<td style="width: 22px;"><img src="/static/img/wyzzicons/' +buttonName[btn]+ '.gif" border=0 unselectable="on" title="' +buttonName[btn]+ '" id="' +buttonName[btn]+ '" class="cmdbutton" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'cmdbutton\'){className=\'buttonOver\'};" onmouseout="if(className==\'buttonOver\'){className=\'cmdbutton\'};" unselectable="on" width="20" height="20"></td>';
+        }
+     }
+	}
+    toolbar += '<td>&nbsp;</td></tr></table>';
+  }
+  
+  
+  // Generate WYSIWYG toolbar2
+  var toolbar2 =  '<table cellpadding="0" cellspacing="0" border="0" class="toolbar" style="width:' + toolbarWidth + 'px;"><tr>';
+  
+  // Output buttons for toolbar2
+  var colNumbers = 0;
+  for (btn in buttonName2) {
+   if ( colNumbers < buttonName2.length ) {
+    colNumbers ++;
+    if(buttonName2[btn] == "separator") {
+      toolbar2 += '<td class="separator">&nbsp;</td>';
+      } else {
+      toolbar2 += '<td style="width: 22px;"><img src="/static/img/wyzzicons/' +buttonName2[btn]+ '.gif" border=0 unselectable="on" title="' +buttonName2[btn]+ '" id="' +buttonName2[btn]+ '" class="cmdbutton" onClick="formatText(this.id,\'' + n + '\');" onmouseover="if(className==\'cmdbutton\'){className=\'buttonOver\'};" onmouseout="if(className==\'buttonOver\'){className=\'cmdbutton\'};" unselectable="on" width="20" height="20"></td>';
+       }
+	  }
+  }
+  toolbar2 += '<td>&nbsp;</td></tr>';
+
+// the foreground color picker
+  var swatchcount = 0;
+  toolbar2 += '<tr><td colspan=' + colNumbers + '>';
+  toolbar2 += '<div id="colorpicker' + n + '" class="colorpicker" style="display:none">';
+    for (clr in buttonColors) {
+      toolbar2 += '<a href="#" title="#' + buttonColors[clr] + '" alt="#' + buttonColors[clr] + '" "class="colorButton" onClick="formatTextColor(\'' + buttonColors[clr] + '\',\'' + n + '\');" style="background: #' + buttonColors[clr] + '">&nbsp;</a>';
+      swatchcount++;
+      if(swatchcount%18==0) {
+        toolbar2 += '<br>';
+      }
+    }
+    toolbar2 += '<img class="closebutton" src="/static/img/wyzzicons/close.gif" border=0 onclick="closeColorPicker(\'colorpicker' + n + '\')"></div>';
+  // the background color picker
+  toolbar2 += '<div id="colorbackpicker' + n + '" class="colorpicker" style="display:none">';
+  for (clr in buttonColors) {
+    toolbar2 += '<a href="#" title="#' + buttonColors[clr] + '" alt="#' + buttonColors[clr] + '" class="colorButton" onClick="formatBackColor(\'' + buttonColors[clr] + '\',\'' + n + '\');" style="background: #' + buttonColors[clr] + '">&nbsp;</a>';
+    swatchcount++;
+    if(swatchcount%18==0) {
+      toolbar2 += '<br>';
+    }
+  }
+  toolbar2 += '<img class="closebutton" src="/static/img/wyzzicons/close.gif" border=0 onclick="closeColorPicker(\'colorbackpicker' + n + '\')"></div>'; 
+  // the font picker
+  toolbar2 += '<div id="fontpicker' + n + '" class="fontpicker" style="display:none">';
+  var fCount = 0;
+  for (fnt in myFonts) {
+   if (fCount < myFonts.length) {
+    fCount ++ ;
+    toolbar2 += '<a href="#" class="fontSelect" onClick="formatFontName(\'' + myFonts[fnt] + '\',\'' + n + '\');" style="font-size:14px;padding: 0px 0px 0px 30px;font-family:' + myFonts[fnt] +'">' + myFonts[fnt] +'</a>';
+    toolbar2 += '<br>';
+   }
+  }
+  toolbar2 += '<img class="closebutton" src="/static/img/wyzzicons/close.gif" border=0 onclick="closeColorPicker(\'fontpicker' + n + '\')"></div>'; 
+  // the special character picker
+  toolbar2 += '<div id="specialpicker' + n + '" class="specialpicker" style="display:none"><table><tr>';
+  var charcount = 0;
+  for (chr in specialChars) {
+   if ( charcount < specialChars.length ) {
+    toolbar2 += '<td><a href="#" onClick="formatSpecialChar(\'' + specialChars[chr] + '\',\'' + n + '\');">' + specialChars[chr] + '</a>&nbsp;</td>';
+    charcount++;
+    if(charcount%10==0) {
+      toolbar2 += '</tr><tr>';
+    }
+   }
+  }
+  toolbar2 += '</tr></table><br><img class="closebutton" src="/static/img/wyzzicons/close.gif" border=0 onclick="closeColorPicker(\'specialpicker' + n + '\')"></div>'; 
+  // the header picker
+  toolbar2 += '<div id="headerpicker' + n + '" class="headerpicker" style="display:none">';
+  var hdrcount = 0;
+  for (hdr in Headers) {
+   if ( hdrcount < Headers.length ) {
+   hdrcount ++;
+    toolbar2 += '<a href="#" class="headerSelect" onClick="formatHeader(\'' + Headers[hdr] + '\',\'' + n + '\');" style="font-size:14px;padding: 0px 0px 0px 30px;font-family:arial">' + Headers[hdr] +'</a>';
+    toolbar2 += '<br>';
+   }
+  }
+  toolbar2 += '<img class="closebutton" src="/static/img/wyzzicons/close.gif" border=0 onclick="closeColorPicker(\'headerpicker' + n + '\')"></div>'; 
+  // Add extra popups here
+  // The help/about box
+  // The copyright and link must remain unaltered
+  toolbar2 += '<div id="helpbox' + n + '" class="helpbox" style="display:none">';
+  toolbar2 += '<div class="help"><h4><img src="/static/img/wyzzicons/wyzzicon.gif" align="middle">Wyzz v' + version + '</h4><br>&copy; 2007 <a href="http://www.wyzz.info" target=_blank>www.wyzz.info</a><br><br></div>';
+  toolbar2 += '<img class="closebutton" src="/static/img/wyzzicons/close.gif" border=0 onclick="closeColorPicker(\'helpbox' + n + '\')"></div></td></tr></table>';   
+
+// Create iframe for editor
+var iframe = '<table cellpadding="0" cellspacing="0" border="0" style="width:' + wyzzW + 'px; height:' + wyzzH + 'px;border: 1px inset #dddddd;"><tr><td valign="top">\n'
+  + '<iframe frameborder="0" id="wysiwyg' + n + '"></iframe>\n'
+  + '</td></tr></table>\n';
+  
+  // Insert toolbar after the textArea
+  document.getElementById(n).insertAdjacentHTML("afterEnd", toolbar + toolbar2 + iframe);
+	
+  // Give the iframe the required height and width
+  document.getElementById("wysiwyg" + n).style.height = wyzzH + "px";
+  document.getElementById("wysiwyg" + n).style.width = wyzzW + "px";
+	
+  // Pass the textarea's existing text into the editor
+  var content = document.getElementById(n).value;
+  var doc = document.getElementById("wysiwyg" + n).contentWindow.document;
+	
+  // Write the textarea's content into the iframe
+  doc.open();
+  if (browserName == "Microsoft Internet Explorer") {
+      doc.write('<link rel="stylesheet" media="screen" type="text/css" href="' + editstyle + '"/>' + content);
+    } else {
+      doc.write('<html><head><link rel="stylesheet" type="text/css" href="' + editstyle + '"/></head><body>' + content + '<br /></body></html>');
+    }
+  doc.close();
+
+//  var browserName = navigator.appName;
+  if (browserName == "Microsoft Internet Explorer"||browserName == "Opera") {    
+    // Make the iframe editable
+    doc.body.contentEditable = true;
+  } else {
+    // Make the iframe editable
+    doc.designMode = "on";  
+  }
+	
+  // Update the textarea with content in WYSIWYG when user submits form
+  // var browserName = navigator.appName;
+  if (browserName == "Microsoft Internet Explorer"||browserName == "Opera") {
+    for (var idx=0; idx < document.forms.length; idx++) {
+      document.forms[idx].attachEvent('onsubmit', function() { updateTextArea(n); });
+    }
+  }
+  else {
+  	for (var idx=0; idx < document.forms.length; idx++) {
+    	document.forms[idx].addEventListener('submit',function OnSumbmit() { updateTextArea(n); }, true);
+    }
+  }
+}
+
+function formatTextColor(color, n, selected) {
+  document.getElementById('wysiwyg' + n).contentWindow.document.execCommand('forecolor', false, color);
+  document.getElementById('colorpicker' + n).style.display = "none";		
+}
+
+function formatBackColor(color, n, selected) {
+  if (browserName == "Microsoft Internet Explorer") {
+    document.getElementById('wysiwyg' + n).contentWindow.document.execCommand('backcolor', false, color);
+  } else {
+    document.getElementById('wysiwyg' + n).contentWindow.document.execCommand('hilitecolor', false, color);
+  }
+  document.getElementById('colorbackpicker' + n).style.display = "none";	
+}
+
+function formatFontName(fontname, n, selected) {
+  document.getElementById('wysiwyg' + n).contentWindow.document.execCommand('fontName', false, fontname);
+  document.getElementById('fontpicker' + n).style.display = "none";	
+}
+
+function formatSpecialChar(charname, n, selected) {
+  insertHTML(charname, n);
+  document.getElementById('specialpicker' + n).style.display = "none";	
+}
+
+function formatHeader(headername, n, selected) {
+  document.getElementById('wysiwyg' + n).contentWindow.document.execCommand('formatBlock', false, '<'+headername+'>');
+  document.getElementById('headerpicker' + n).style.display = "none";	
+}
+
+function formatText(id, n, selected) {
+  if(mode==0&&id!='htmlmode') {
+    alert('Function unavailable in "View Source" mode');
+  } else {
+    // When user clicks button make sure it always targets correct textarea
+    document.getElementById("wysiwyg" + n).contentWindow.focus();	
+    if(id=="upsize") {
+      var currentFontSize = document.getElementById("wysiwyg"+n).contentWindow.document.queryCommandValue("FontSize");
+      if(currentFontSize == ''||!currentFontSize) currentFontSize = 3; // fudge for FF
+        if(currentFontSize < 7) {
+          var newFontSize = parseInt(currentFontSize) + 1;
+        } else {
+          var newFontSize = currentFontSize;
+        }
+        document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontSize", false, newFontSize);
+      }
+    else if(id=="downsize") {
+      var currentFontSize = document.getElementById("wysiwyg"+n).contentWindow.document.queryCommandValue("FontSize");
+      if(currentFontSize > 1) {
+          var newFontSize = currentFontSize - 1;
+        } else {
+          var newFontSize = currentFontSize;
+        }
+        document.getElementById("wysiwyg" + n).contentWindow.document.execCommand("FontSize", false, newFontSize);
+      }
+      else if(id=="forecolor"){
+        if(document.getElementById('colorpicker' + n).style.display == ""){
+          document.getElementById('colorpicker' + n).style.display = "none";
+        } else {
+          document.getElementById('colorpicker' + n).style.display = "";	
+        }
+      } 
+      else if(id=="backcolor"){
+        if(document.getElementById('colorbackpicker' + n).style.display == ""){
+          document.getElementById('colorbackpicker' + n).style.display = "none";
+        } else {
+            document.getElementById('colorbackpicker' + n).style.display = "";	
+        }
+      }
+      else if(id=="font"){
+        if(document.getElementById('fontpicker' + n).style.display == ""){
+          document.getElementById('fontpicker' + n).style.display = "none";
+        } else {
+          document.getElementById('fontpicker' + n).style.display = "";	
+        }
+      } 
+      else if(id=="specialchar"){
+        if(document.getElementById('specialpicker' + n).style.display == ""){
+          document.getElementById('specialpicker' + n).style.display = "none";
+        } else {
+          document.getElementById('specialpicker' + n).style.display = "";	
+        }
+      }     
+      else if(id=="headers"){
+        if(document.getElementById('headerpicker' + n).style.display == ""){
+          document.getElementById('headerpicker' + n).style.display = "none";
+        } else {
+          document.getElementById('headerpicker' + n).style.display = "";	
+        }
+      } 
+      else if(id=="htmlmode"){		
+        var getDoc = document.getElementById("wysiwyg" + n).contentWindow.document;      
+        if(mode == 1) {
+          if(navigator.appName == "Microsoft Internet Explorer"||browserName == "Opera") {
+            var iHTML = getDoc.body.innerHTML;
+            getDoc.body.innerText = iHTML;
+          } else {
+            var html = document.createTextNode(getDoc.body.innerHTML);
+            getDoc.body.innerHTML = "";
+            getDoc.body.appendChild(html);
+          }
+          getDoc.body.style.fontSize = "12px";
+          getDoc.body.style.fontFamily = "Courier New";
+          mode = 0;
+        } else {
+          if(navigator.appName == "Microsoft Internet Explorer"||browserName == "Opera") {
+            var iText = getDoc.body.innerText;
+            getDoc.body.innerHTML = iText;
+          } else {
+            var html = getDoc.body.ownerDocument.createRange();
+            html.selectNodeContents(getDoc.body);
+            getDoc.body.innerHTML = html.toString();
+          }
+          mode = 1;        
+        }
+      }
+      else if(id=="help"){	
+        if(document.getElementById('helpbox' + n).style.display == ""){
+          document.getElementById('helpbox' + n).style.display = "none";
+        } else {
+          document.getElementById('helpbox' + n).style.display = "";	
+        }    
+      }
+      else if(id=="link"){
+        // var browserName = navigator.appName;	 	 
+        if (browserName == "Microsoft Internet Explorer") {  
+          var target = confirm('Should this link open in a new window?\n\nOK = Open in NEW Window\nCancel = Open in THIS window');
+          document.getElementById("wysiwyg" + n).contentWindow.document.execCommand('createLink',true,' ');
+          if(target == true)
+          {
+            document.getElementById("wysiwyg" + n).contentWindow.document.selection.createRange().parentElement().target="_blank";
+          }
+        } else {
+          insertLink(n);
+        }
+      }
+      else if(id=="insertimage") {
+        // var browserName = navigator.appName;	 	 
+        if (browserName == "Microsoft Internet Explorer") {       
+          document.getElementById("wysiwyg" + n).contentWindow.document.execCommand(id, true, null);
+        } else {
+          insertImage(n);
+        }
+      }
+      else {
+        document.getElementById("wysiwyg" + n).contentWindow.document.execCommand(id, false, null);
+    }
+  }
+}
+
+function insertHTML(html, n) {
+  // var browserName = navigator.appName;	 	 
+	if (browserName == "Microsoft Internet Explorer") {	  
+	  document.getElementById('wysiwyg' + n).contentWindow.document.selection.createRange().pasteHTML(html);   
+	} 
+	 
+	else {
+	  var div = document.getElementById('wysiwyg' + n).contentWindow.document.createElement("span");
+		 
+		div.innerHTML = html;
+		var node = insertNodeAtSelection(div, n);		
+	}
+}
+
+function insertNodeAtSelection(insertNode, n) {
+  // get current selection
+  var sel = document.getElementById('wysiwyg' + n).contentWindow.getSelection();
+
+  // get the first range of the selection (there's almost always only one range)
+  var range = sel.getRangeAt(0);
+
+  // deselect everything
+  sel.removeAllRanges();
+
+  // remove content of current selection from document
+  range.deleteContents();
+
+  // get location of current selection
+  var container = range.startContainer;
+  var pos = range.startOffset;
+
+  // make a new range for the new selection
+  range = document.createRange();
+
+  if (container.nodeType==3 && insertNode.nodeType==3) {
+
+    // if we insert text in a textnode, do optimized insertion
+    container.insertData(pos, insertNode.nodeValue);
+
+    // put cursor after inserted text
+    range.setEnd(container, pos+insertNode.length);
+    range.setStart(container, pos+insertNode.length);
+  } 
+	
+	else {
+    var afterNode;
+    
+		if (container.nodeType==3) {
+      // when inserting into a textnode we create 2 new textnodes and put the insertNode in between
+      var textNode = container;
+      container = textNode.parentNode;
+      var text = textNode.nodeValue;
+
+      // text before the split
+      var textBefore = text.substr(0,pos);
+
+      // text after the split
+      var textAfter = text.substr(pos);
+
+      var beforeNode = document.createTextNode(textBefore);
+      afterNode = document.createTextNode(textAfter);
+
+      // insert the 3 new nodes before the old one
+      container.insertBefore(afterNode, textNode);
+      container.insertBefore(insertNode, afterNode);
+      container.insertBefore(beforeNode, insertNode);
+
+      // remove the old node
+      container.removeChild(textNode);
+    } 
+	
+	  else {
+      // else simply insert the node
+      afterNode = container.childNodes[pos];
+      container.insertBefore(insertNode, afterNode);
+    }
+
+    range.setEnd(afterNode, 0);
+    range.setStart(afterNode, 0);
+  }
+
+  sel.addRange(range);
+}
+
+function updateTextArea(n) {
+  if(xhtml_out == 1) {
+    document.getElementById(n).value = h2x(document.getElementById("wysiwyg" + n).contentWindow.document.body);
+  } else {
+    document.getElementById(n).value = document.getElementById("wysiwyg" + n).contentWindow.document.body.innerHTML;
+  }       
+}
+  
+
+function grabSelectedText(n){ 
+   // var browserName = navigator.appName; 
+   var selectedText = ''; 
+   // for IE 
+   if (browserName == "Microsoft Internet Explorer"||browserName == "Opera") { 
+      var theText = document.getElementById("wysiwyg" + n).contentWindow.document.selection; 
+      if(theText.type =='Text')   { 
+         var newText = theText.createRange(); 
+         selectedText = newText.text; 
+      } 
+   } 
+   // for Mozilla/Netscape 
+   else { 
+      var selectedText = document.getElementById("wysiwyg" + n).contentWindow.document.getSelection(); 
+   } 
+   return selectedText; 
+} 
+
+/*var myrules = {
+		'input[type=submit]' : function(element){
+			element.onclick = function(){
+				// Your onclick event goes here - eg;
+				// load a page - do an AJAX etc.;
+			}
+		}
+	};
+	
+Behaviour.register(myrules);*/

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/editarea.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/editarea.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,79 @@
+/**************** body and tag styles ****************/
+	body, p {
+	  margin-top: 0px;	  
+	  margin-bottom: 30px;
+          background-color: #fefefe; 
+          font-family: Verdana, Arial, Helvetica, sans-serif; 
+          color: #333333;
+          font-size: 13px;
+	  }
+
+	#container {
+	  width: 750px;
+	  margin: 0 auto;
+	  font-family: Verdana, Arial, Helvetica, sans-serif;
+	  font-size: 11px;
+	  line-height: 1.6em;
+	  color: #666666;
+	  background-color: #FFFFFF;
+	  }
+	  
+	#container2 {
+	  width: 746px;
+	  margin: 0 auto;
+	  font-family: Verdana, Arial, Helvetica, sans-serif;
+	  font-size: 11px;
+	  line-height: 1.6em;
+	  color: #666666;
+	  background-color: #FFFFFF;
+	  border-bottom: 2px solid #2763A5;
+	  }
+        
+	pre {
+	  font-family: "courier new", sans-serif;
+	  font-weight: normal;
+	  font-size: 12px;
+	  color: #6DA6E2;
+	  background-color: #FFFFFF;
+	  }        
+		
+	h1 {
+	  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+	  font-weight: normal;
+	  font-size: 32px;
+	  color: #6DA6E2;
+	  margin-bottom: 30px;
+	  background-color: #FFFFFF;
+	  }
+		
+	h2 {
+	  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+	  font-weight: normal;
+	  font-size: 28px;
+	  color: #6DA6E2;
+	  margin-bottom: 30px;
+	  background-color: #FFFFFF;
+	  }
+		
+        h3 {
+	  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+	  font-weight: normal;
+	  font-size: 24px;
+	  color: #6DA6E2;
+	  margin-bottom: 30px;
+	  background-color: #FFFFFF;
+	  }
+        
+	a {
+	  color: #6DA6E2;
+	  background-color: #FFFFFF;
+	  text-decoration: none;
+	  font-weight: bold;
+	  }
+
+	a:hover {
+	  background-color: #FFFFFF;
+	  color: inherit;
+	  font-weight: bold;
+	  text-decoration: underline;
+	  }
\ No newline at end of file

Added: jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/style.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/plugins/WyzzEditor/share/web/static/wyzzstyles/style.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,24 @@
+/* WYSIWYG EDITOR */
+
+/* Toolbar */
+.toolbar   { border: 1px solid #999999; height: 24px; background-color:#cccccc; }
+.wyzz_alleditor	{ display: block; border:1px #aaa solid; width:520px; background:#e0e0e0; padding:2px;position:relative;}
+.wyzz_alleditor div 	{ display:block;}
+
+/* Command Buttons */
+.cmdbutton     { width: 20px; height: 20px; border: 1px solid transparent; margin: 0px; padding: 0px; background: transparent; } 
+.closebutton { float:right; padding: 2px; }
+.buttonOver { width: 20px; height: 20px; border: 1px solid #999999; margin: 0px; padding: 0px;  }
+.separator { width: 2px; border-left: 1px solid #eeeeee; margin: 0px; padding: 0px; }
+
+/* others */
+.colorpicker, .colorbackpicker, .fontpicker, .headerpicker, .helpbox, .linkdialog	{ position:absolute; width: 216px; background:#eee; display:block; padding:0px; margin-top:0px; border:1px #555 solid;line-height:1.4}
+.specialpicker	{ position:absolute; width: 216px; background:#eee; display:block; padding-top:20px;padding-left:20px; margin-top:0px; border:1px #555 solid;line-height:1.4}
+.help {margin: 10px; font: 12px bold verdana,helvetica,arial,sans-serif black; text-align:center }
+.help h4 {font: 18px bold verdana,helvetica,arial,sans-serif black; padding-top:10px}
+.colorpicker a, .colorbackpicker a { border:1px #fff solid; height:10px; width:10px; font-size:0.01em; display:block;float:left; margin-right:0px;}
+.colorpicker a:hover, .colorbackpicker a:hover { border:1px #f00 solid;}
+.fontpicker a, .headerpicker a { color:#333;text-decoration:none;background:#eee;}
+.fontpicker a:hover, .headerpicker a:hover, .specialpicker a:hover { color: #666 }
+.specialpicker a { color:#333;font-family:arial;text-decoration:none;background:#eee;height:13px; width:12px;font-size:14px}
+.charbutton { width:12px;height:14px; }

Modified: jifty/branches/virtual-models/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/content.html
==============================================================================
--- jifty/branches/virtual-models/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/content.html	(original)
+++ jifty/branches/virtual-models/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/content.html	Mon May  7 16:28:32 2007
@@ -33,6 +33,7 @@
 }
 my $body;
 my $schema;
+use Pod::Simple::HTML;
 my $converter = Pod::Simple::HTML->new();
 if($n !~ /^Jifty\//) {
     if ($total_body =~ /package (.*?)::Schema;(.*)package/ismx) {

Modified: jifty/branches/virtual-models/share/po/en.po
==============================================================================
--- jifty/branches/virtual-models/share/po/en.po	(original)
+++ jifty/branches/virtual-models/share/po/en.po	Mon May  7 16:28:32 2007
@@ -15,10 +15,41 @@
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm:38
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"request to reset your password for %1.\n"
+"\n"
+"If you don't want to reset your password just ignore this message.\n"
+"\n"
+"To reset your password, click on the link below:\n"
+"\n"
+"%2\n"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:41
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"wants to use %1. \n"
+"\n"
+"We need to make sure that we got your email address right.  Click on the link below to get started:\n"
+"\n"
+"%2\n"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:125
 msgid "!=>< allowed"
 msgstr ""
 
+#: lib/Jifty/Notification.pm:94
+#. ($appname, Jifty->config->framework('AdminEmail')
+msgid "%1 <%2>"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:115
 #. ($label)
 msgid "%1 after"
@@ -34,7 +65,7 @@
 msgid "%1 contains"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:87
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:141
 #. ($collection-> count)
 msgid "%1 entries"
 msgstr ""
@@ -94,23 +125,32 @@
 msgid "(any)"
 msgstr ""
 
-#: lib/Jifty/Web/Form/.Field.pm.swp:44 lib/Jifty/Web/Form/Field.pm:549
-msgid "@{[$self->current_value]}"
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:58
+msgid ". Your email address has now been confirmed."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:96
+msgid "A link to reset your password has been sent to your email account."
+msgstr ""
+
+#: lib/Jifty/Notification.pm:96
+#. ($appname)
+msgid "A notification from %1!"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:19
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:443
 msgid "Actions"
 msgstr ""
 
-#: share/web/templates/_elements/nav:5
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
 msgid "Administration"
 msgstr ""
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
 msgid "Administration mode is enabled."
 msgstr ""
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
 msgid "Alert"
 msgstr ""
 
@@ -122,11 +162,19 @@
 msgid "Any field contains"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/action/dhandler:25 share/web/templates/__jifty/admin/model/dhandler:21
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:131
+msgid "Anyway, the software has logged this error."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+msgid "Authentication token"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:489 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:59
 msgid "Back to the admin console"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:461
 msgid "Back to the application"
 msgstr ""
 
@@ -139,7 +187,7 @@
 msgid "Calendar"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/update:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:338
 msgid "Cancel"
 msgstr ""
 
@@ -151,11 +199,15 @@
 msgid "Close window"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/view:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:382
 msgid "Confirm delete?"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/new_item:25
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+msgid "Confirmation resent."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:213
 msgid "Create"
 msgstr ""
 
@@ -168,11 +220,11 @@
 msgid "Created"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:3
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:415
 msgid "Database Administration"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/view:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:380
 msgid "Delete"
 msgstr ""
 
@@ -180,11 +232,11 @@
 msgid "Deleted"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:28 share/web/templates/__jifty/admin/model/dhandler:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:458 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:486 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:56
 msgid "Done?"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/view:40 share/web/templates/__jifty/halo:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:388 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
 msgid "Edit"
 msgstr ""
 
@@ -193,77 +245,166 @@
 msgid "Edit %1"
 msgstr ""
 
-#: share/web/templates/dhandler:7
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:23 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:32
+msgid "Email"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+msgid "Email address"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+msgid "Email address confirmed?"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1158
+msgid "Foo cannot contain -, *, +, or ?."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1152
+msgid "Foo cannot contain uppercase letters."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1136
+msgid "Foo values are always in lowercase."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:27
+msgid "For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:138 share/web/templates/dhandler:7
 msgid "Go back home..."
 msgstr ""
 
-#: share/web/templates/_elements/sidebar:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
+msgid "Hashed Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:44
+msgid "Head on back home"
+msgstr ""
+
+#: lib/Jifty/I18N.pm:19 lib/Jifty/I18N.pm:23
+#. ('World')
+msgid "Hello, %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
 #. ($u->$method()
 msgid "Hiya, %1."
 msgstr ""
 
-#: share/web/templates/_elements/nav:3
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
 msgid "Home"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:1
-msgid "Jifty Administrative Console"
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+msgid "How should I display your name to other users?"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1090
+msgid "I changed $field for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:64
+msgid "I'm not sure how this happened."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
+msgid "Internal error"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/toc.html:6
-msgid "Jifty Developer Documentation Online"
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/content.html:6
-msgid "Jifty Pod Online"
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
+msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
 msgstr ""
 
-#: share/web/templates/_elements/wrapper:18
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
+msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+msgid "It looks like you're already confirmed."
+msgstr ""
+
+#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
 msgid "Loading..."
 msgstr ""
 
-#: share/web/templates/__jifty/admin/model/dhandler:9
-#. ($object_type)
-msgid "Manage %1 records"
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:106
+msgid "Login"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/model/dhandler:11
-msgid "Manage records:"
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+msgid "Login with a password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+msgid "Login!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:123
+msgid "Logout"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+msgid "Lost your password?"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:46 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:473
+#. ($object_type)
+msgid "Manage records: [_1]"
 msgstr ""
 
 #: share/web/templates/__jifty/error/mason_internal_error:1
 msgid "Mason error"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:9
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:429
 msgid "Models"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:113
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:81
+msgid "New password"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:172
 msgid "Next Page"
 msgstr ""
 
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+msgid "Nickname"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+msgid "No account yet? It's quick and easy. "
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:130
 msgid "No field contains"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:85
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:139
 msgid "No items found"
 msgstr ""
 
-#: lib/Jifty/Web.pm:300
+#: lib/Jifty/Web.pm:302
 msgid "No request to handle"
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/index.html:5
-msgid "Online Documentation"
-msgstr ""
-
-#: share/web/templates/_elements/nav:6
+#: lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm:26
 msgid "Online docs"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:80
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:134
 #. ($page, $collection->pager->last_page)
 msgid "Page %1 of %2"
 msgstr ""
@@ -276,20 +417,44 @@
 msgid "Parent"
 msgstr ""
 
-#: lib/Jifty/Record.pm:264 lib/Jifty/Record.pm:343 lib/Jifty/Record.pm:68
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+msgid "Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+msgid "Passwords need to be at least six characters long"
+msgstr ""
+
+#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
 msgid "Permission denied"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:108
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:66
+msgid "Please email us!"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:163
 msgid "Previous Page"
 msgstr ""
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
+msgid "Really, really sorry."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:37
+msgid "Remember me?"
+msgstr ""
+
 #: share/web/templates/__jifty/halo:69
 #. ($frame->{'render_time'})
 msgid "Rendered in %1s"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/action/dhandler:20
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:78
+msgid "Reset lost password"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:53
 msgid "Run the action"
 msgstr ""
 
@@ -297,58 +462,112 @@
 msgid "SQL Statements"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/update:21
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:327
 msgid "Save"
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/content.html:50
-msgid "Schema"
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:304
+msgid "Search"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/search:18
-msgid "Search"
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:119
+msgid "Send"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+msgid "Send a link to reset your password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:109 lib/Jifty/Plugin/Authentication/Password/View.pm:114
+msgid "Send a password reminder"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:111
+msgid "Sign up"
 msgstr ""
 
-#: share/web/templates/dhandler:1
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+msgid "Sign up for an account!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+msgid "Signup"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+#. ($msg)
+msgid "Something bad happened and we couldn't create your account: %1"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:149
+msgid "Something went awry"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:124 share/web/templates/dhandler:1
 msgid "Something's not quite right"
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/index.html:16 share/web/templates/__jifty/online_docs/index.html:18
-msgid "Table of Contents"
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:132
+msgid "Sorry about this."
 msgstr ""
 
-#: lib/Jifty/Action.pm:876
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#. ($new_email)
+msgid "That %1 doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action.pm:878
 msgid "That doesn't look like a correct value"
 msgstr ""
 
-#: lib/Jifty/Action/Record.pm:248
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+msgid "That doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action/Record.pm:249
 msgid "That doesn't look right, but I don't know why"
 msgstr ""
 
-#: lib/Jifty/Action/Record.pm:180
+#: lib/Jifty/Action/Record.pm:181
 msgid "The passwords you typed didn't match each other"
 msgstr ""
 
-#: lib/Jifty/Web.pm:363
+#: lib/Jifty/Web.pm:365
 msgid "There was an error completing the request.  Please try again later."
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:81
+msgid "There was an error setting your password."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:37
+msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:419
 msgid "This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records."
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:7
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:425
 msgid "To disable this administrative console, add \"AdminMode: 0\" under the \"framework:\" settings in the config file (etc/config.yml)."
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:72
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:127
 msgid "Toggle search"
 msgstr ""
 
-#: share/web/templates/__jifty/error/mason_internal_error:6
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:173 share/web/templates/__jifty/error/mason_internal_error:6
 msgid "Try again"
 msgstr ""
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+msgid "Try again later. We're really, really sorry."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:53
+msgid "Type that again?"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Update.pm:156
 msgid "Updated"
 msgstr ""
@@ -357,35 +576,120 @@
 msgid "Variables"
 msgstr ""
 
-#: share/web/templates/index.html:1
+#: lib/Jifty.pm:27
+msgid "W00t"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
+msgid "We've sent a confirmation message to your email box."
+msgstr ""
+
+#: lib/Jifty/I18N.pm:31
+#. ('Bob', 'World')
+msgid "Welcome %1 to the %2"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#. ($user->name)
+msgid "Welcome back, %1."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:40
+#. ($appname)
+msgid "Welcome to %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2. "
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
 msgid "Welcome to your new Jifty application"
 msgstr ""
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
+msgid "You don't exist."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:130
+msgid "You got to a page that we don't think exists."
+msgstr ""
+
 #: share/web/templates/dhandler:5
 msgid "You got to a page that we don't think exists.  Anyway, the software has logged this error. Sorry about this."
 msgstr ""
 
-#: lib/Jifty/Action.pm:863
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:44
+msgid "You have already confirmed your account."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:98
+msgid "You lost your password. A link to reset it will be sent to the following email address:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:115
+msgid "You lost your password. A reminder will be send to the following mail:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
+msgid "You may have mistyped your email address or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
+msgid "You may have mistyped your email or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Action.pm:865
 msgid "You need to fill in this field"
 msgstr ""
 
-#: share/web/templates/index.html:3
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
 #. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
 msgid "You said you wanted a pony. (Source %1)"
 msgstr ""
 
-#: share/web/templates/_elements/sidebar:7
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+msgid "You're already logged in."
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
 msgid "You're not currently signed in."
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/header:22
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
+msgid "Your browser can remember your login for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:87
+msgid "Your password has been reset.  Welcome back."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+msgid "Your password should be at least six characters"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:246
 msgid "asc"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/header:41
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:264
 msgid "desc"
 msgstr ""
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:31
+msgid "email address"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:46
+msgid "for now, and try to forget that we let you down."
+msgstr ""
+
 #: lib/Jifty/Manual/PageRegions.pod:188
 msgid "text of the link"
 msgstr ""
@@ -393,3 +697,11 @@
 #: lib/Jifty/Manual/PageRegions.pod:225
 msgid "text of the link that hides"
 msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:37
+msgid "type your password again"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1050
+msgid "warning"
+msgstr ""

Modified: jifty/branches/virtual-models/share/po/fr.po
==============================================================================
--- jifty/branches/virtual-models/share/po/fr.po	(original)
+++ jifty/branches/virtual-models/share/po/fr.po	Mon May  7 16:28:32 2007
@@ -8,21 +8,67 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "POT-Creation-Date: 2006-10-24 18:00+ZONE\n"
-"PO-Revision-Date: 2006-11-02 09:34+ZONE\n"
+"PO-Revision-Date: 2007-04-16 23:18+ZONE\n"
 "Last-Translator: AGOSTINI Yves <agostini at univ-metz.fr>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm:38
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"request to reset your password for %1.\n"
+"\n"
+"If you don't want to reset your password just ignore this message.\n"
+"\n"
+"To reset your password, click on the link below:\n"
+"\n"
+"%2\n"
+msgstr ""
+"\n"
+"Vous avez demandé le changement de votre mot de passe sur %1.\n"
+"\n"
+"Pour effectuer ce changement cliquez sur le lien ci-dessous :\n"
+"\n"
+"%2\n"
+"\n"
+"Si vous ne voulez pas changer votre mot de passe, ignorez simplement ce message.\n"
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:41
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"wants to use %1. \n"
+"\n"
+"We need to make sure that we got your email address right.  Click on the link below to get started:\n"
+"\n"
+"%2\n"
+msgstr ""
+"\n"
+"Ce message vous permet de confirmer votre adresse mail, si vous voulez utiliser\n"
+" %1\n"
+"\n"
+"Pour confirmer votre adresse mail, cliquez sur le lien ci-dessous :\n"
+"\n"
+"%2\n"
+
 #: lib/Jifty/Action/Record/Search.pm:125
 msgid "!=>< allowed"
 msgstr "!=>< autorisés"
 
+#: lib/Jifty/Notification.pm:94
+#. ($appname, Jifty->config->framework('AdminEmail')
+msgid "%1 <%2>"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:115
 #. ($label)
 msgid "%1 after"
-msgstr "%1 aprés"
+msgstr "%1 après"
 
 #: lib/Jifty/Action/Record/Search.pm:116
 #. ($label)
@@ -34,7 +80,7 @@
 msgid "%1 contains"
 msgstr "%1 contient"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:87
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:141
 #. ($collection-> count)
 msgid "%1 entries"
 msgstr "%1 enregistements"
@@ -42,12 +88,12 @@
 #: lib/Jifty/Action/Record/Search.pm:123
 #. ($label)
 msgid "%1 greater or equal to"
-msgstr "%1 supérieur ou égal à"
+msgstr "%1 supérieur ou égal à "
 
 #: lib/Jifty/Action/Record/Search.pm:121
 #. ($label)
 msgid "%1 greater than"
-msgstr "%1 supérieur à"
+msgstr "%1 supérieur à "
 
 #: lib/Jifty/Action/Record/Search.pm:108
 #. ($label)
@@ -67,7 +113,7 @@
 #: lib/Jifty/Action/Record/Search.pm:122
 #. ($label)
 msgid "%1 less than"
-msgstr "%1 inférieur à"
+msgstr "%1 inférieur à "
 
 #: share/web/templates/__jifty/error/mason_internal_error:31 share/web/templates/__jifty/error/mason_internal_error:35 share/web/templates/__jifty/error/mason_internal_error:39
 #. ($path, $line)
@@ -94,23 +140,32 @@
 msgid "(any)"
 msgstr ""
 
-#: lib/Jifty/Web/Form/.Field.pm.swp:44 lib/Jifty/Web/Form/Field.pm:549
-msgid "@{[$self->current_value]}"
-msgstr ""
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:58
+msgid ". Your email address has now been confirmed."
+msgstr ". Votre adresse mail est confirmée."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:96
+msgid "A link to reset your password has been sent to your email account."
+msgstr "Une URL pour changer votre mots de passe, vous a été transmis par mail. "
+
+#: lib/Jifty/Notification.pm:96
+#. ($appname)
+msgid "A notification from %1!"
+msgstr "Message de %1!"
 
-#: share/web/templates/__jifty/admin/index.html:19
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:443
 msgid "Actions"
 msgstr ""
 
-#: share/web/templates/_elements/nav:5
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
 msgid "Administration"
 msgstr ""
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
 msgid "Administration mode is enabled."
 msgstr "Mode d'administration activé."
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
 msgid "Alert"
 msgstr "Alerte"
 
@@ -122,11 +177,19 @@
 msgid "Any field contains"
 msgstr "Un champs contient"
 
-#: share/web/templates/__jifty/admin/action/dhandler:25 share/web/templates/__jifty/admin/model/dhandler:21
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:131
+msgid "Anyway, the software has logged this error."
+msgstr "Cette erreur a été enregistrée par le logiciel."
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+msgid "Authentication token"
+msgstr "Token d'authentification"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:489 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:59
 msgid "Back to the admin console"
 msgstr "Retour à l'interface d'admin"
 
-#: share/web/templates/__jifty/admin/index.html:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:461
 msgid "Back to the application"
 msgstr "Retour à l'application"
 
@@ -139,7 +202,7 @@
 msgid "Calendar"
 msgstr "Calendrier"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:338
 msgid "Cancel"
 msgstr "Annuler"
 
@@ -151,28 +214,32 @@
 msgid "Close window"
 msgstr "Fermer la fenêtre"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:382
 msgid "Confirm delete?"
 msgstr "Confirmer l'effacement ?"
 
-#: share/web/templates/__jifty/admin/fragments/list/new_item:25
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+msgid "Confirmation resent."
+msgstr "Confirmation transmise."
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:213
 msgid "Create"
 msgstr "Enregistrer"
 
 #: lib/Jifty/Action/Record/Create.pm:81
 #. (ref($record)
 msgid "Create of %1 failed: %2"
-msgstr "La création de %1 a échoué: %2"
+msgstr "La création de %1 a échoué : %2"
 
 #: lib/Jifty/Action/Record/Create.pm:105
 msgid "Created"
 msgstr "Créé"
 
-#: share/web/templates/__jifty/admin/index.html:3
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:415
 msgid "Database Administration"
 msgstr "Administration de la Base de Données"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:380
 msgid "Delete"
 msgstr "Effacer"
 
@@ -180,11 +247,11 @@
 msgid "Deleted"
 msgstr "Effacé"
 
-#: share/web/templates/__jifty/admin/index.html:28 share/web/templates/__jifty/admin/model/dhandler:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:458 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:486 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:56
 msgid "Done?"
-msgstr ""
+msgstr "Fini ?"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:40 share/web/templates/__jifty/halo:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:388 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
 msgid "Edit"
 msgstr "Editer"
 
@@ -193,77 +260,170 @@
 msgid "Edit %1"
 msgstr "Editer %1"
 
-#: share/web/templates/dhandler:7
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:23 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:32
+msgid "Email"
+msgstr "Mail"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+msgid "Email address"
+msgstr "Adresse mail"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+msgid "Email address confirmed?"
+msgstr "Adresse mail confirmée ?"
+
+#: lib/Jifty/Action.pm:1158
+msgid "Foo cannot contain -, *, +, or ?."
+msgstr "Cette donnée ne doit pas contenir -, *, +, ou ?."
+
+#: lib/Jifty/Action.pm:1152
+msgid "Foo cannot contain uppercase letters."
+msgstr "Cette donnée ne doit pas contenir de majuscule."
+
+#: lib/Jifty/Action.pm:1136
+msgid "Foo values are always in lowercase."
+msgstr "Cett donnée doit toujours être en minuscule."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:27
+msgid "For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:138 share/web/templates/dhandler:7
 msgid "Go back home..."
 msgstr "Retour..."
 
-#: share/web/templates/_elements/sidebar:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
+msgid "Hashed Password"
+msgstr "Mot de passe crypté"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:44
+msgid "Head on back home"
+msgstr ""
+
+#: lib/Jifty/I18N.pm:19 lib/Jifty/I18N.pm:23
+#. ('World')
+msgid "Hello, %1!"
+msgstr "Bonjour, %1"
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
 #. ($u->$method()
 msgid "Hiya, %1."
 msgstr "Bonjour, %1"
 
-#: share/web/templates/_elements/nav:3
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
 msgid "Home"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:1
-msgid "Jifty Administrative Console"
-msgstr ""
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+msgid "How should I display your name to other users?"
+msgstr "Nom affiché"
 
-#: share/web/templates/__jifty/online_docs/toc.html:6
-msgid "Jifty Developer Documentation Online"
+#: lib/Jifty/Action.pm:1090
+msgid "I changed $field for you"
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/content.html:6
-msgid "Jifty Pod Online"
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:64
+msgid "I'm not sure how this happened."
 msgstr ""
 
-#: share/web/templates/_elements/wrapper:18
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
+msgid "Internal error"
+msgstr "Erreur interne"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
+msgstr "Il ne semble pas y avoir de compte sous ce nom."
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
+msgstr "Cette adresse semble utilisée par quelqu'un d'autre. Vous avez peut-être un autre compte ?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
+msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
+msgstr "Votre compte existe déjà . Vous voulez peut-être plutôt <a href=\"/login\">vous connecter</a> ?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
+msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
+msgstr "Les mots de passe sont différents. Ré-essayer ?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+msgid "It looks like you're already confirmed."
+msgstr "Votre adresse à déjà été confirmée."
+
+#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
 msgid "Loading..."
 msgstr "Chargement..."
 
-#: share/web/templates/__jifty/admin/model/dhandler:9
-#. ($object_type)
-msgid "Manage %1 records"
-msgstr ""
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:106
+msgid "Login"
+msgstr "Identification"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+msgid "Login with a password"
+msgstr "S'identifier avec un mot de passe"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+msgid "Login!"
+msgstr "Identification"
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:123
+msgid "Logout"
+msgstr "Déconnection"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+msgid "Lost your password?"
+msgstr "Vous avez oublié votre mot de passe ?"
 
-#: share/web/templates/__jifty/admin/model/dhandler:11
-msgid "Manage records:"
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:46 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:473
+#. ($object_type)
+msgid "Manage records: [_1]"
 msgstr ""
 
 #: share/web/templates/__jifty/error/mason_internal_error:1
 msgid "Mason error"
 msgstr "Erreur Mason"
 
-#: share/web/templates/__jifty/admin/index.html:9
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:429
 msgid "Models"
 msgstr "Modèles"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:113
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:81
+msgid "New password"
+msgstr "Nouveau mot de passe"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:172
 msgid "Next Page"
 msgstr "Page Suivante"
 
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+msgid "Nickname"
+msgstr "Surnom"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+msgid "No account yet? It's quick and easy. "
+msgstr "Pas encore de compte ? C'est facile et rapide. "
+
 #: lib/Jifty/Action/Record/Search.pm:130
 msgid "No field contains"
 msgstr "Aucun champs contient"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:85
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:139
 msgid "No items found"
 msgstr "Aucun enregistrement"
 
-#: lib/Jifty/Web.pm:300
+#: lib/Jifty/Web.pm:302
 msgid "No request to handle"
 msgstr "Aucune requête à traiter"
 
-#: share/web/templates/__jifty/online_docs/index.html:5
+#:
 msgid "Online Documentation"
 msgstr "Documentation en ligne"
 
-#: share/web/templates/_elements/nav:6
+#: lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm:26
 msgid "Online docs"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:80
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:134
 #. ($page, $collection->pager->last_page)
 msgid "Page %1 of %2"
 msgstr "Page %1 / %2"
@@ -276,24 +436,48 @@
 msgid "Parent"
 msgstr ""
 
-#: lib/Jifty/Record.pm:264 lib/Jifty/Record.pm:343 lib/Jifty/Record.pm:68
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+msgid "Password"
+msgstr "Mot de passe"
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+msgid "Passwords need to be at least six characters long"
+msgstr "Il faut au minimum six caractères"
+
+#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
 msgid "Permission denied"
 msgstr "Autorisation refusée"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:108
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:66
+msgid "Please email us!"
+msgstr "Envoyez nous un mail !"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:163
 msgid "Previous Page"
 msgstr "Page précédente"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
+msgid "Really, really sorry."
+msgstr "Vraiment désolé"
+
 #:
 msgid "Record created"
 msgstr "Enregistrement créé"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:37
+msgid "Remember me?"
+msgstr "S'en rappeler"
+
 #: share/web/templates/__jifty/halo:69
 #. ($frame->{'render_time'})
 msgid "Rendered in %1s"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/action/dhandler:20
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:78
+msgid "Reset lost password"
+msgstr "Changement de mot de passe"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:53
 msgid "Run the action"
 msgstr "Exécuter l'action"
 
@@ -301,58 +485,120 @@
 msgid "SQL Statements"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/update:21
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:327
 msgid "Save"
 msgstr "Enregistrer"
 
-#: share/web/templates/__jifty/online_docs/content.html:50
+#:
 msgid "Schema"
 msgstr "Schéma"
 
-#: share/web/templates/__jifty/admin/fragments/list/search:18
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:304
 msgid "Search"
 msgstr "Chercher"
 
-#: share/web/templates/dhandler:1
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:119
+msgid "Send"
+msgstr "Enregistrer"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+msgid "Send a link to reset your password"
+msgstr "Recevoir un lien pour changer votre mot de passe"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:109 lib/Jifty/Plugin/Authentication/Password/View.pm:114
+msgid "Send a password reminder"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:111
+msgid "Sign up"
+msgstr "S'enregistrer"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+msgid "Sign up for an account!"
+msgstr "Enregistrez vous pour avoir un compte !"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+msgid "Signup"
+msgstr "Enregistrement"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+#. ($msg)
+msgid "Something bad happened and we couldn't create your account: %1"
+msgstr "Un problème nous empêche de créer votre compte: %1"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:149
+msgid "Something went awry"
+msgstr "Problème"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:124 share/web/templates/dhandler:1
 msgid "Something's not quite right"
 msgstr "Problème"
 
-#: share/web/templates/__jifty/online_docs/index.html:16 share/web/templates/__jifty/online_docs/index.html:18
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:132
+msgid "Sorry about this."
+msgstr "Désolé."
+
+#:
 msgid "Table of Contents"
 msgstr "Table des matières"
 
-#: lib/Jifty/Action.pm:876
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#. ($new_email)
+msgid "That %1 doesn't look like an email address."
+msgstr "%1 ne ressemble pas à une adresse mail."
+
+#: lib/Jifty/Action.pm:878
 msgid "That doesn't look like a correct value"
 msgstr "Valeur incorecte"
 
-#: lib/Jifty/Action/Record.pm:248
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+msgid "That doesn't look like an email address."
+msgstr "Cela ne ressemble pas à une adresse mail."
+
+#: lib/Jifty/Action/Record.pm:249
 msgid "That doesn't look right, but I don't know why"
 msgstr "Problème"
 
-#: lib/Jifty/Action/Record.pm:180
+#: lib/Jifty/Action/Record.pm:181
 msgid "The passwords you typed didn't match each other"
 msgstr "Les mots de passe tapés ne sont pas identiques"
 
-#: lib/Jifty/Web.pm:363
+#: lib/Jifty/Web.pm:365
 msgid "There was an error completing the request.  Please try again later."
 msgstr "Problème lors de l'exécution de cette requête. Ré-essayez plus tard."
 
-#: share/web/templates/__jifty/admin/index.html:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:81
+msgid "There was an error setting your password."
+msgstr "Problème pendant l'enregistrement de votre mot de passe."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:37
+msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:419
 msgid "This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records."
 msgstr "Cette page vous permet de gérer vos enregistrements dans la base. Vous trouverez ci-dessous la listes des tables. Vous pouvez ajouter, effacer ou modifier les enregistements."
 
-#: share/web/templates/__jifty/admin/index.html:7
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:425
 msgid "To disable this administrative console, add \"AdminMode: 0\" under the \"framework:\" settings in the config file (etc/config.yml)."
 msgstr "Pour désactiver cette console d'administration, ajoutez \"AdminMode: 0\" dans la rubrique \"framework:\" du fichier de configuration (etc/config.yml)."
 
-#: share/web/templates/__jifty/admin/fragments/list/list:72
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:127
 msgid "Toggle search"
 msgstr "Rechercher"
 
-#: share/web/templates/__jifty/error/mason_internal_error:6
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:173 share/web/templates/__jifty/error/mason_internal_error:6
 msgid "Try again"
 msgstr "Ré-essayer"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+msgid "Try again later. We're really, really sorry."
+msgstr "Ré-essayez, nous sommes vraiment désolés."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:53
+msgid "Type that again?"
+msgstr "Confirmez"
+
 #: lib/Jifty/Action/Record/Update.pm:156
 msgid "Updated"
 msgstr "Modification"
@@ -361,35 +607,120 @@
 msgid "Variables"
 msgstr ""
 
-#: share/web/templates/index.html:1
+#: lib/Jifty.pm:27
+msgid "W00t"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
+msgid "We've sent a confirmation message to your email box."
+msgstr "Nous vous avons envoyé un mail de confirmation."
+
+#: lib/Jifty/I18N.pm:31
+#. ('Bob', 'World')
+msgid "Welcome %1 to the %2"
+msgstr "Bienvenue %1 sur %2"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#. ($user->name)
+msgid "Welcome back, %1."
+msgstr "Re-bonjour, %1."
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:40
+#. ($appname)
+msgid "Welcome to %1!"
+msgstr "Bienvenue sur %1 !"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2."
+msgstr "Bienvenue sur %1, %2."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2. "
+msgstr "Bienvenue sur %1, %2. "
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
 msgid "Welcome to your new Jifty application"
 msgstr "Bienvenue sur votre nouvelle application Jifty"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
+msgid "You don't exist."
+msgstr "Votre compte n'existe pas."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:130
+msgid "You got to a page that we don't think exists."
+msgstr "Vous voulez une page qui n'existe pas."
+
 #: share/web/templates/dhandler:5
 msgid "You got to a page that we don't think exists.  Anyway, the software has logged this error. Sorry about this."
 msgstr "Cette page n'existe pas."
 
-#: lib/Jifty/Action.pm:863
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:44
+msgid "You have already confirmed your account."
+msgstr "Votre compte à déjà été confirmé."
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:98
+msgid "You lost your password. A link to reset it will be sent to the following email address:"
+msgstr "Vous avez perdu votre mot de passe. Un lien pour changer ce mot de passe sera envoyé à l'adresse suivante :"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:115
+msgid "You lost your password. A reminder will be send to the following mail:"
+msgstr "Vous avez perdu votre mot de passe. Un lien pour changer ce mot de passe sera envoyé à l'adresse suivante :"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
+msgid "You may have mistyped your email address or password. Give it another shot."
+msgstr "Vous vous êtes trompé dans votre mail ou votre mot de passe. Ré-essayez."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
+msgid "You may have mistyped your email or password. Give it another shot."
+msgstr "Vous vous êtes trompé dans votre mail ou votre mot de passe. Ré-essayez."
+
+#: lib/Jifty/Action.pm:865
 msgid "You need to fill in this field"
 msgstr "Information obligatoire"
 
-#: share/web/templates/index.html:3
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
 #. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
 msgid "You said you wanted a pony. (Source %1)"
 msgstr ""
 
-#: share/web/templates/_elements/sidebar:7
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+msgid "You're already logged in."
+msgstr "Vous êtes déjà connecté."
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
 msgid "You're not currently signed in."
 msgstr "Vous n'êtes pas encore connecté."
 
-#: share/web/templates/__jifty/admin/fragments/list/header:22
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
+msgid "Your browser can remember your login for you"
+msgstr "Votre navigateur peut mémoriser cette identification"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:87
+msgid "Your password has been reset.  Welcome back."
+msgstr "Votre mot de passe à été changé."
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+msgid "Your password should be at least six characters"
+msgstr "Votre mot de passe doit contenir au moins six caractères"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:246
 msgid "asc"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/header:41
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:264
 msgid "desc"
 msgstr ""
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:31
+msgid "email address"
+msgstr "adresse mail"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:46
+msgid "for now, and try to forget that we let you down."
+msgstr ""
+
 #: lib/Jifty/Manual/PageRegions.pod:188
 msgid "text of the link"
 msgstr ""
@@ -397,3 +728,11 @@
 #: lib/Jifty/Manual/PageRegions.pod:225
 msgid "text of the link that hides"
 msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:37
+msgid "type your password again"
+msgstr "confirmez votre mot de passe"
+
+#: lib/Jifty/Action.pm:1050
+msgid "warning"
+msgstr ""

Modified: jifty/branches/virtual-models/share/po/ja.po
==============================================================================
--- jifty/branches/virtual-models/share/po/ja.po	(original)
+++ jifty/branches/virtual-models/share/po/ja.po	Mon May  7 16:28:32 2007
@@ -15,10 +15,41 @@
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm:38
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"request to reset your password for %1.\n"
+"\n"
+"If you don't want to reset your password just ignore this message.\n"
+"\n"
+"To reset your password, click on the link below:\n"
+"\n"
+"%2\n"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:41
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"wants to use %1. \n"
+"\n"
+"We need to make sure that we got your email address right.  Click on the link below to get started:\n"
+"\n"
+"%2\n"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:125
 msgid "!=>< allowed"
 msgstr "! = > < は利用できません"
 
+#: lib/Jifty/Notification.pm:94
+#. ($appname, Jifty->config->framework('AdminEmail')
+msgid "%1 <%2>"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:115
 #. ($label)
 msgid "%1 after"
@@ -34,7 +65,7 @@
 msgid "%1 contains"
 msgstr "%1 を含む"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:87
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:141
 #. ($collection-> count)
 msgid "%1 entries"
 msgstr "%1 件"
@@ -94,23 +125,32 @@
 msgid "(any)"
 msgstr "(指定なし)"
 
-#: lib/Jifty/Web/Form/.Field.pm.swp:44 lib/Jifty/Web/Form/Field.pm:549
-msgid "@{[$self->current_value]}"
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:58
+msgid ". Your email address has now been confirmed."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:96
+msgid "A link to reset your password has been sent to your email account."
+msgstr ""
+
+#: lib/Jifty/Notification.pm:96
+#. ($appname)
+msgid "A notification from %1!"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:19
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:443
 msgid "Actions"
 msgstr "操作"
 
-#: share/web/templates/_elements/nav:5
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
 msgid "Administration"
 msgstr ""
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
 msgid "Administration mode is enabled."
 msgstr "管理モードが有効になっています"
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
 msgid "Alert"
 msgstr "注意"
 
@@ -122,11 +162,19 @@
 msgid "Any field contains"
 msgstr "検索したい文字列"
 
-#: share/web/templates/__jifty/admin/action/dhandler:25 share/web/templates/__jifty/admin/model/dhandler:21
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:131
+msgid "Anyway, the software has logged this error."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+msgid "Authentication token"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:489 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:59
 msgid "Back to the admin console"
 msgstr "管理画面に戻る"
 
-#: share/web/templates/__jifty/admin/index.html:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:461
 msgid "Back to the application"
 msgstr "アプリケーションに戻る"
 
@@ -139,7 +187,7 @@
 msgid "Calendar"
 msgstr "カレンダー"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:338
 msgid "Cancel"
 msgstr "キャンセル"
 
@@ -151,11 +199,15 @@
 msgid "Close window"
 msgstr "閉じる"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:382
 msgid "Confirm delete?"
 msgstr "本当に削除しますか"
 
-#: share/web/templates/__jifty/admin/fragments/list/new_item:25
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+msgid "Confirmation resent."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:213
 msgid "Create"
 msgstr "作成"
 
@@ -168,11 +220,11 @@
 msgid "Created"
 msgstr "作成しました"
 
-#: share/web/templates/__jifty/admin/index.html:3
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:415
 msgid "Database Administration"
 msgstr "データベース管理"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:380
 msgid "Delete"
 msgstr "削除"
 
@@ -180,11 +232,11 @@
 msgid "Deleted"
 msgstr "削除しました"
 
-#: share/web/templates/__jifty/admin/index.html:28 share/web/templates/__jifty/admin/model/dhandler:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:458 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:486 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:56
 msgid "Done?"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/view:40 share/web/templates/__jifty/halo:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:388 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
 msgid "Edit"
 msgstr "編集"
 
@@ -193,77 +245,178 @@
 msgid "Edit %1"
 msgstr "%1 を編集"
 
-#: share/web/templates/dhandler:7
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:23 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:32
+msgid "Email"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+msgid "Email address"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+msgid "Email address confirmed?"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1158
+msgid "Foo cannot contain -, *, +, or ?."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1152
+msgid "Foo cannot contain uppercase letters."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1136
+msgid "Foo values are always in lowercase."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:27
+msgid "For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:138 share/web/templates/dhandler:7
 msgid "Go back home..."
 msgstr "ホームページに戻ります…"
 
-#: share/web/templates/_elements/sidebar:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
+msgid "Hashed Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:44
+msgid "Head on back home"
+msgstr ""
+
+#: lib/Jifty/I18N.pm:19 lib/Jifty/I18N.pm:23
+#. ('World')
+msgid "Hello, %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
 #. ($u->$method()
 msgid "Hiya, %1."
 msgstr "%1 さん、こんにちは"
 
-#: share/web/templates/_elements/nav:3
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
 msgid "Home"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:1
-msgid "Jifty Administrative Console"
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+msgid "How should I display your name to other users?"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1090
+msgid "I changed $field for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:64
+msgid "I'm not sure how this happened."
 msgstr ""
 
-#: share/web/templates/__jifty/online_docs/toc.html:6
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
+msgid "Internal error"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
+msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
+msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+msgid "It looks like you're already confirmed."
+msgstr ""
+
+#:
 msgid "Jifty Developer Documentation Online"
 msgstr "開発者向けオンラインドキュメント"
 
-#: share/web/templates/__jifty/online_docs/content.html:6
+#:
 msgid "Jifty Pod Online"
 msgstr "オンラインドキュメント"
 
-#: share/web/templates/_elements/wrapper:18
+#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
 msgid "Loading..."
 msgstr "読込み中…"
 
-#: share/web/templates/__jifty/admin/model/dhandler:9
-#. ($object_type)
-msgid "Manage %1 records"
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:106
+msgid "Login"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+msgid "Login with a password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+msgid "Login!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:123
+msgid "Logout"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/model/dhandler:11
-msgid "Manage records:"
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+msgid "Lost your password?"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:46 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:473
+#. ($object_type)
+msgid "Manage records: [_1]"
 msgstr ""
 
 #: share/web/templates/__jifty/error/mason_internal_error:1
 msgid "Mason error"
 msgstr "Mason エラー"
 
-#: share/web/templates/__jifty/admin/index.html:9
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:429
 msgid "Models"
 msgstr "モデル"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:113
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:81
+msgid "New password"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:172
 msgid "Next Page"
 msgstr "次のページ"
 
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+msgid "Nickname"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+msgid "No account yet? It's quick and easy. "
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:130
 msgid "No field contains"
 msgstr "排除したい文字列"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:85
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:139
 msgid "No items found"
 msgstr "見つかりませんでした"
 
-#: lib/Jifty/Web.pm:300
+#: lib/Jifty/Web.pm:302
 msgid "No request to handle"
 msgstr "処理できるリクエストがありません"
 
-#: share/web/templates/__jifty/online_docs/index.html:5
+#:
 msgid "Online Documentation"
 msgstr "オンラインドキュメント"
 
-#: share/web/templates/_elements/nav:6
+#: lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm:26
 msgid "Online docs"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/fragments/list/list:80
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:134
 #. ($page, $collection->pager->last_page)
 msgid "Page %1 of %2"
 msgstr "%1 / %2 ページ"
@@ -276,20 +429,44 @@
 msgid "Parent"
 msgstr ""
 
-#: lib/Jifty/Record.pm:264 lib/Jifty/Record.pm:343 lib/Jifty/Record.pm:68
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+msgid "Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+msgid "Passwords need to be at least six characters long"
+msgstr ""
+
+#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
 msgid "Permission denied"
 msgstr "権限がありません"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:108
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:66
+msgid "Please email us!"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:163
 msgid "Previous Page"
 msgstr "前のページ"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
+msgid "Really, really sorry."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:37
+msgid "Remember me?"
+msgstr ""
+
 #: share/web/templates/__jifty/halo:69
 #. ($frame->{'render_time'})
 msgid "Rendered in %1s"
 msgstr ""
 
-#: share/web/templates/__jifty/admin/action/dhandler:20
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:78
+msgid "Reset lost password"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:53
 msgid "Run the action"
 msgstr "実行"
 
@@ -297,58 +474,120 @@
 msgid "SQL Statements"
 msgstr "SQL文"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:21
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:327
 msgid "Save"
 msgstr "保存"
 
-#: share/web/templates/__jifty/online_docs/content.html:50
+#:
 msgid "Schema"
 msgstr "スキーマ"
 
-#: share/web/templates/__jifty/admin/fragments/list/search:18
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:304
 msgid "Search"
 msgstr "検索"
 
-#: share/web/templates/dhandler:1
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:119
+msgid "Send"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+msgid "Send a link to reset your password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:109 lib/Jifty/Plugin/Authentication/Password/View.pm:114
+msgid "Send a password reminder"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:111
+msgid "Sign up"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+msgid "Sign up for an account!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+msgid "Signup"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+#. ($msg)
+msgid "Something bad happened and we couldn't create your account: %1"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:149
+msgid "Something went awry"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:124 share/web/templates/dhandler:1
 msgid "Something's not quite right"
 msgstr "原因不明のエラーです"
 
-#: share/web/templates/__jifty/online_docs/index.html:16 share/web/templates/__jifty/online_docs/index.html:18
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:132
+msgid "Sorry about this."
+msgstr ""
+
+#:
 msgid "Table of Contents"
 msgstr "目次"
 
-#: lib/Jifty/Action.pm:876
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#. ($new_email)
+msgid "That %1 doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action.pm:878
 msgid "That doesn't look like a correct value"
 msgstr "値が不適切なようです"
 
-#: lib/Jifty/Action/Record.pm:248
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+msgid "That doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action/Record.pm:249
 msgid "That doesn't look right, but I don't know why"
 msgstr "原因不明のエラーです"
 
-#: lib/Jifty/Action/Record.pm:180
+#: lib/Jifty/Action/Record.pm:181
 msgid "The passwords you typed didn't match each other"
 msgstr "パスワードが一致しません"
 
-#: lib/Jifty/Web.pm:363
+#: lib/Jifty/Web.pm:365
 msgid "There was an error completing the request.  Please try again later."
 msgstr "リクエストの処理中にエラーが発生しました。しばらく待ってから再度試してみてください"
 
-#: share/web/templates/__jifty/admin/index.html:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:81
+msgid "There was an error setting your password."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:37
+msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:419
 msgid "This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records."
 msgstr "ここでは Jifty データベースのレコードを管理できます。下にデータベースの全テーブルが一覧されているはずですので、自由に表示・作成・削除・修正してください。"
 
-#: share/web/templates/__jifty/admin/index.html:7
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:425
 msgid "To disable this administrative console, add \"AdminMode: 0\" under the \"framework:\" settings in the config file (etc/config.yml)."
 msgstr "この管理画面を無効にするには、設定ファイル(etc/config.yml)の \"framework:\" の項目の下に \"AdminMode: 0\" を追加してください。"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:72
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:127
 msgid "Toggle search"
 msgstr "検索の切り替え"
 
-#: share/web/templates/__jifty/error/mason_internal_error:6
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:173 share/web/templates/__jifty/error/mason_internal_error:6
 msgid "Try again"
 msgstr "再度試してみてください"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+msgid "Try again later. We're really, really sorry."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:53
+msgid "Type that again?"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Update.pm:156
 msgid "Updated"
 msgstr "更新しました"
@@ -357,35 +596,120 @@
 msgid "Variables"
 msgstr ""
 
-#: share/web/templates/index.html:1
+#: lib/Jifty.pm:27
+msgid "W00t"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
+msgid "We've sent a confirmation message to your email box."
+msgstr ""
+
+#: lib/Jifty/I18N.pm:31
+#. ('Bob', 'World')
+msgid "Welcome %1 to the %2"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#. ($user->name)
+msgid "Welcome back, %1."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:40
+#. ($appname)
+msgid "Welcome to %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2. "
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
 msgid "Welcome to your new Jifty application"
 msgstr "Jifty の新規アプリケーションです"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
+msgid "You don't exist."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:130
+msgid "You got to a page that we don't think exists."
+msgstr ""
+
 #: share/web/templates/dhandler:5
 msgid "You got to a page that we don't think exists.  Anyway, the software has logged this error. Sorry about this."
 msgstr "このページは存在しません。エラーとして記録しておきました。ご不便をお詫びいたします"
 
-#: lib/Jifty/Action.pm:863
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:44
+msgid "You have already confirmed your account."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:98
+msgid "You lost your password. A link to reset it will be sent to the following email address:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:115
+msgid "You lost your password. A reminder will be send to the following mail:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
+msgid "You may have mistyped your email address or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
+msgid "You may have mistyped your email or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Action.pm:865
 msgid "You need to fill in this field"
 msgstr "必須項目です"
 
-#: share/web/templates/index.html:3
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
 #. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
 msgid "You said you wanted a pony. (Source %1)"
 msgstr "こんなのが欲しかったんでしょう?(出典:%1)"
 
-#: share/web/templates/_elements/sidebar:7
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+msgid "You're already logged in."
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
 msgid "You're not currently signed in."
 msgstr "ログインしていません"
 
-#: share/web/templates/__jifty/admin/fragments/list/header:22
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
+msgid "Your browser can remember your login for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:87
+msgid "Your password has been reset.  Welcome back."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+msgid "Your password should be at least six characters"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:246
 msgid "asc"
 msgstr "昇順"
 
-#: share/web/templates/__jifty/admin/fragments/list/header:41
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:264
 msgid "desc"
 msgstr "降順"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:31
+msgid "email address"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:46
+msgid "for now, and try to forget that we let you down."
+msgstr ""
+
 #: lib/Jifty/Manual/PageRegions.pod:188
 msgid "text of the link"
 msgstr ""
@@ -393,3 +717,11 @@
 #: lib/Jifty/Manual/PageRegions.pod:225
 msgid "text of the link that hides"
 msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:37
+msgid "type your password again"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1050
+msgid "warning"
+msgstr ""

Added: jifty/branches/virtual-models/share/po/ru.po
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/share/po/ru.po	Mon May  7 16:28:32 2007
@@ -0,0 +1,583 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Ruslan Zakirov <Ruslan.Zakirov at gmail.com>.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.01\n"
+"POT-Creation-Date: 2007-05-01 03:09+0400\n"
+"PO-Revision-Date: 2007-05-01 03:09+0400\n"
+"Last-Translator: Ruslan Zakirov <Ruslan.Zakirov at gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm:38
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"request to reset your password for %1.\n"
+"\n"
+"If you don't want to reset your password just ignore this message.\n"
+"\n"
+"To reset your password, click on the link below:\n"
+"\n"
+"%2\n"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:41
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"wants to use %1. \n"
+"\n"
+"We need to make sure that we got your email address right.  Click on the link below to get started:\n"
+"\n"
+"%2\n"
+msgstr ""
+
+#: lib/Jifty/Action/Record/Search.pm:125
+msgid "!=>< allowed"
+msgstr "допустимы !=><"
+
+#: lib/Jifty/Notification.pm:94
+#. ($appname, Jifty->config->framework('AdminEmail')
+msgid "%1 <%2>"
+msgstr ""
+
+#: lib/Jifty/Action/Record/Search.pm:115
+#. ($label)
+msgid "%1 after"
+msgstr "%1 после"
+
+#: lib/Jifty/Action/Record/Search.pm:116
+#. ($label)
+msgid "%1 before"
+msgstr "%1 до"
+
+#: lib/Jifty/Action/Record/Search.pm:112
+#. ($label)
+msgid "%1 contains"
+msgstr "%1 содержит"
+
+#: lib/Jifty/Action/Record/Search.pm:123
+#. ($label)
+msgid "%1 greater or equal to"
+msgstr "%1 больше или равно"
+
+#: lib/Jifty/Action/Record/Search.pm:121
+#. ($label)
+msgid "%1 greater than"
+msgstr "%1 больше чем"
+
+#: lib/Jifty/Action/Record/Search.pm:108
+#. ($label)
+msgid "%1 is not"
+msgstr "%1 не"
+
+#: lib/Jifty/Action/Record/Search.pm:113
+#. ($label)
+msgid "%1 lacks"
+msgstr "%1 не содержит"
+
+#: lib/Jifty/Action/Record/Search.pm:124
+#. ($label)
+msgid "%1 less or equal to"
+msgstr "%1 меньше или равно"
+
+#: lib/Jifty/Action/Record/Search.pm:122
+#. ($label)
+msgid "%1 less than"
+msgstr "%1 меньше чем"
+
+#: share/web/templates/__jifty/error/mason_internal_error:31 share/web/templates/__jifty/error/mason_internal_error:35 share/web/templates/__jifty/error/mason_internal_error:39
+#. ($path, $line)
+#. ($file, $line)
+msgid "%1 line %2"
+msgstr "%1 строка %2"
+
+#: share/web/templates/__jifty/halo:119
+#. ($_->[3])
+msgid "%1 seconds"
+msgstr "%1 секунд"
+
+#: lib/Jifty/Action/Record/Search.pm:117
+#. ($label)
+msgid "%1 since"
+msgstr "%1 после"
+
+#: lib/Jifty/Action/Record/Search.pm:118
+#. ($label)
+msgid "%1 until"
+msgstr "%1 до"
+
+#: lib/Jifty/Action/Record/Search.pm:77
+msgid "(any)"
+msgstr "(любое)"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:58
+msgid ". Your email address has now been confirmed."
+msgstr ". Ваш адрес был подтвержден."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:96
+msgid "A link to reset your password has been sent to your email account."
+msgstr "Ссылка для сброса пароля была отправлена на ваш почтовый ящик."
+
+#: lib/Jifty/Notification.pm:96
+#. ($appname)
+msgid "A notification from %1!"
+msgstr "Уведомление от %1!"
+
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
+msgid "Administration"
+msgstr "Администрирование"
+
+#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
+msgid "Administration mode is enabled."
+msgstr "Режим администрирования активирован."
+
+#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
+msgid "Alert"
+msgstr "Внимание"
+
+#: lib/Jifty/Action/Record/Create.pm:82
+msgid "An error occurred.  Try again later"
+msgstr "Произошла ошибка. Попробуйте позже"
+
+#: lib/Jifty/Action/Record/Search.pm:129
+msgid "Any field contains"
+msgstr "Любой поле содержит"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:131
+msgid "Anyway, the software has logged this error."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+msgid "Authentication token"
+msgstr ""
+
+#: share/web/templates/__jifty/halo:117
+msgid "Bindings"
+msgstr ""
+
+#: share/web/templates/helpers/calendar.html:4
+#. (_ &><body class="calpopup"><a href="#" onclick="window.close()
+msgid "Calendar"
+msgstr "Календарь"
+
+#: share/web/templates/__jifty/halo:81
+msgid "Children"
+msgstr "Потомки"
+
+#: share/web/templates/helpers/calendar.html:4
+msgid "Close window"
+msgstr "Закрыть окно"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+msgid "Confirmation resent."
+msgstr "Подтверждение выслано повторно."
+
+#: lib/Jifty/Action/Record/Create.pm:81
+#. (ref($record)
+msgid "Create of %1 failed: %2"
+msgstr "Создание %1 провалилось: %2"
+
+#: lib/Jifty/Action/Record/Create.pm:105
+msgid "Created"
+msgstr "Создано"
+
+#: lib/Jifty/Action/Record/Delete.pm:76
+msgid "Deleted"
+msgstr "Удалено"
+
+#: share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
+msgid "Edit"
+msgstr "Редактировать"
+
+#: lib/Jifty/Mason/Halo.pm:104
+#. ($comp_name)
+msgid "Edit %1"
+msgstr "Изменить %1"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:23 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:32
+msgid "Email"
+msgstr "Почта"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+msgid "Email address"
+msgstr "Адрес почты"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+msgid "Email address confirmed?"
+msgstr "Адрес почты подтвержден?"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:27
+msgid "For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:138 share/web/templates/dhandler:7
+msgid "Go back home..."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
+msgid "Hashed Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:44
+msgid "Head on back home"
+msgstr ""
+
+#: lib/Jifty/I18N.pm:19 lib/Jifty/I18N.pm:23
+#. ('World')
+msgid "Hello, %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
+#. ($u->$method()
+msgid "Hiya, %1."
+msgstr "Алоха, %1."
+
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
+msgid "Home"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+msgid "How should I display your name to other users?"
+msgstr "Как вас представлять другим пользователям?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:64
+msgid "I'm not sure how this happened."
+msgstr "Я не уверен, как это произошло."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
+msgid "Internal error"
+msgstr "Внутренняя ошибка"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:63 lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
+msgstr "Кажется в системе нет пользователя с таким именем."
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
+msgstr "Кто другой уже использует этот адрес. Может быть у вас уже есть учетная запись?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
+msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
+msgstr "Видимо у вас уже есть учетная запись. Возможно вы хотите <a href=\"/login\">войти</a>?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
+msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
+msgstr "Вы ввели разные пароли в оба поля. Может еще разок?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+msgid "It looks like you're already confirmed."
+msgstr "Вы уже подтверждали"
+
+#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
+msgid "Loading..."
+msgstr "Загрузка..."
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:109
+msgid "Login"
+msgstr "Вход"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+msgid "Login with a password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+msgid "Login!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:126
+msgid "Logout"
+msgstr "Выход"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+msgid "Lost your password?"
+msgstr "Забыли пароль?"
+
+#: share/web/templates/__jifty/error/mason_internal_error:1
+msgid "Mason error"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:80
+msgid "New password"
+msgstr "Новый пароль"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+msgid "Nickname"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+msgid "No account yet? It's quick and easy. "
+msgstr "Нет учетной записи? Это быстро и легко. "
+
+#: lib/Jifty/Action/Record/Search.pm:130
+msgid "No field contains"
+msgstr ""
+
+#: lib/Jifty/Web.pm:302
+msgid "No request to handle"
+msgstr ""
+
+#: lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm:26
+msgid "Online docs"
+msgstr "Online документация"
+
+#: share/web/templates/__jifty/halo:1
+msgid "Page info"
+msgstr "информация о странице"
+
+#: share/web/templates/__jifty/halo:72
+msgid "Parent"
+msgstr "Родитель"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+msgid "Password"
+msgstr "Пароль"
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+msgid "Passwords need to be at least six characters long"
+msgstr "Пароль должен быть не менее шести симфолов"
+
+#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
+msgid "Permission denied"
+msgstr "Доступ запрещен"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:66
+msgid "Please email us!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
+msgid "Really, really sorry."
+msgstr "Очень сожалеем."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:37
+msgid "Remember me?"
+msgstr "Запомнить?"
+
+#: share/web/templates/__jifty/halo:69
+#. ($frame->{'render_time'})
+msgid "Rendered in %1s"
+msgstr "Сгенерировано за %1 сек."
+
+#: share/web/templates/__jifty/halo:111
+msgid "SQL Statements"
+msgstr "SQL запросы"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:118
+msgid "Send"
+msgstr "Отправить"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:96
+msgid "Send a link to reset your password"
+msgstr "Отправить ссылку сброса пароля"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:108 lib/Jifty/Plugin/Authentication/Password/View.pm:113
+msgid "Send a password reminder"
+msgstr "Отправить напоминание пароля"
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:114
+msgid "Sign up"
+msgstr "Зарегистроваться"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+msgid "Sign up for an account!"
+msgstr "Завести учетную запись!"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+msgid "Signup"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+#. ($msg)
+msgid "Something bad happened and we couldn't create your account: %1"
+msgstr "Что-то неправильное случилось и мы не смогли создать вашу учетную запись: %1"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:149
+msgid "Something went awry"
+msgstr "Что-то пошло наперекосяк"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:124 share/web/templates/dhandler:1
+msgid "Something's not quite right"
+msgstr "Что-то не совсем верно"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:132
+msgid "Sorry about this."
+msgstr "Сожалеем об этом."
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#. ($new_email)
+msgid "That %1 doesn't look like an email address."
+msgstr "Строка %1 не похожа на адрес почты"
+
+#: lib/Jifty/Action.pm:878
+msgid "That doesn't look like a correct value"
+msgstr "Не похоже на допустимое значение"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+msgid "That doesn't look like an email address."
+msgstr "Не похоже на почтовый адрес"
+
+#: lib/Jifty/Action/Record.pm:249
+msgid "That doesn't look right, but I don't know why"
+msgstr "Неправильно, но неизвестно почему"
+
+#: lib/Jifty/Action/Record.pm:181
+msgid "The passwords you typed didn't match each other"
+msgstr "Введенные пароли не совпадают"
+
+#: lib/Jifty/Web.pm:365
+msgid "There was an error completing the request.  Please try again later."
+msgstr "Во время выпонения запроса произошла ошибка. Пожалуйста попробуйте позже."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:81
+msgid "There was an error setting your password."
+msgstr "Не получилось установить пароль."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:37
+msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:173 share/web/templates/__jifty/error/mason_internal_error:6
+msgid "Try again"
+msgstr "Попробовать еще"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+msgid "Try again later. We're really, really sorry."
+msgstr "Попробуйте еще позже. Мы очень-очень сожалеем."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:53
+msgid "Type that again?"
+msgstr "Введите еще раз"
+
+#: lib/Jifty/Action/Record/Update.pm:156
+msgid "Updated"
+msgstr "Обновленно"
+
+#: share/web/templates/__jifty/halo:93
+msgid "Variables"
+msgstr "Переменные"
+
+#: lib/Jifty.pm:27
+msgid "W00t"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
+msgid "We've sent a confirmation message to your email box."
+msgstr "Мы послали сообщение для потдтверждения на ваш электронный адрес."
+
+#: lib/Jifty/I18N.pm:31
+#. ('Bob', 'World')
+msgid "Welcome %1 to the %2"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#. ($user->name)
+msgid "Welcome back, %1."
+msgstr "Рады вас видеть снова, %1."
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:40
+#. ($appname)
+msgid "Welcome to %1!"
+msgstr "Добро пожаловать на сайт %1!"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2."
+msgstr "Добро пожаловать на сайт %1, %2."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2. "
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
+msgid "Welcome to your new Jifty application"
+msgstr "Добро пожаловать в ваше новое Jifty-приложение"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
+msgid "You don't exist."
+msgstr "Вы не существуете."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:130
+msgid "You got to a page that we don't think exists."
+msgstr "Вы послали на страницу, которая не существует."
+
+#: share/web/templates/dhandler:5
+msgid "You got to a page that we don't think exists.  Anyway, the software has logged this error. Sorry about this."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:44
+msgid "You have already confirmed your account."
+msgstr "Вы уже подтверждали учетную запись."
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+msgid "You lost your password. A link to reset it will be sent to the following email address:"
+msgstr "Вы забыли пароль. Ссылка для сброса пароля будет отправлена на адрес: %1"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:114
+msgid "You lost your password. A reminder will be send to the following mail:"
+msgstr "Вы забыли пароль. Напоминание будет отправлено на адрес: %1"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
+msgid "You may have mistyped your email or password. Give it another shot."
+msgstr "Должно быть вы ввели неправильно адрес или пароль. Попробуйте еще разок."
+
+#: lib/Jifty/Action.pm:865
+msgid "You need to fill in this field"
+msgstr "Вы должны заполнить это поле"
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
+#. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
+msgid "You said you wanted a pony. (Source %1)"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+msgid "You're already logged in."
+msgstr "Вы уже вошли."
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
+msgid "You're not currently signed in."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
+msgid "Your browser can remember your login for you"
+msgstr "Ваш браузер может запомнить ваш логин за вас"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:87
+msgid "Your password has been reset.  Welcome back."
+msgstr "ваш пароль был сброшен. Мы рады вас снова видеть."
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+msgid "Your password should be at least six characters"
+msgstr "Ваш пароль должен состоять из шести исмволов минимум"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:31
+msgid "email address"
+msgstr "адрес почты"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:46
+msgid "for now, and try to forget that we let you down."
+msgstr ""
+
+#: lib/Jifty/Manual/PageRegions.pod:188
+msgid "text of the link"
+msgstr "текст ссылки"
+
+#: lib/Jifty/Manual/PageRegions.pod:225
+msgid "text of the link that hides"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:37
+msgid "type your password again"
+msgstr "введите ваг пароль снова"
+
+#: lib/Jifty/Action.pm:1050
+msgid "warning"
+msgstr "предупреждение"

Modified: jifty/branches/virtual-models/share/po/zh_cn.po
==============================================================================
--- jifty/branches/virtual-models/share/po/zh_cn.po	(original)
+++ jifty/branches/virtual-models/share/po/zh_cn.po	Mon May  7 16:28:32 2007
@@ -14,10 +14,41 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm:38
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"request to reset your password for %1.\n"
+"\n"
+"If you don't want to reset your password just ignore this message.\n"
+"\n"
+"To reset your password, click on the link below:\n"
+"\n"
+"%2\n"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:41
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"wants to use %1. \n"
+"\n"
+"We need to make sure that we got your email address right.  Click on the link below to get started:\n"
+"\n"
+"%2\n"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:125
 msgid "!=>< allowed"
 msgstr "可使用 !=>< 符号"
 
+#: lib/Jifty/Notification.pm:94
+#. ($appname, Jifty->config->framework('AdminEmail')
+msgid "%1 <%2>"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:115
 #. ($label)
 msgid "%1 after"
@@ -33,7 +64,7 @@
 msgid "%1 contains"
 msgstr "%1 包含"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:87
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:141
 #. ($collection-> count)
 msgid "%1 entries"
 msgstr "%1 条记录"
@@ -93,23 +124,32 @@
 msgid "(any)"
 msgstr "(任意)"
 
-#: lib/Jifty/Web/Form/.Field.pm.swp:44 lib/Jifty/Web/Form/Field.pm:549
-msgid "@{[$self->current_value]}"
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:58
+msgid ". Your email address has now been confirmed."
 msgstr ""
 
-#: share/web/templates/__jifty/admin/index.html:19
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:96
+msgid "A link to reset your password has been sent to your email account."
+msgstr ""
+
+#: lib/Jifty/Notification.pm:96
+#. ($appname)
+msgid "A notification from %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:443
 msgid "Actions"
 msgstr "操作"
 
-#: share/web/templates/_elements/nav:5
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
 msgid "Administration"
 msgstr "管理接口"
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
 msgid "Administration mode is enabled."
 msgstr "系统管理模式开启中."
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
 msgid "Alert"
 msgstr "请注意"
 
@@ -121,11 +161,19 @@
 msgid "Any field contains"
 msgstr "任意字段包含"
 
-#: share/web/templates/__jifty/admin/action/dhandler:25 share/web/templates/__jifty/admin/model/dhandler:21
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:131
+msgid "Anyway, the software has logged this error."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+msgid "Authentication token"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:489 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:59
 msgid "Back to the admin console"
 msgstr "回到管理界面"
 
-#: share/web/templates/__jifty/admin/index.html:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:461
 msgid "Back to the application"
 msgstr "回到应用程序"
 
@@ -138,7 +186,7 @@
 msgid "Calendar"
 msgstr "日历"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:338
 msgid "Cancel"
 msgstr "取消"
 
@@ -150,11 +198,15 @@
 msgid "Close window"
 msgstr "关闭窗口"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:382
 msgid "Confirm delete?"
 msgstr "确实要删除吗?"
 
-#: share/web/templates/__jifty/admin/fragments/list/new_item:25
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+msgid "Confirmation resent."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:213
 msgid "Create"
 msgstr "创建"
 
@@ -167,11 +219,11 @@
 msgid "Created"
 msgstr "成功建立项目."
 
-#: share/web/templates/__jifty/admin/index.html:3
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:415
 msgid "Database Administration"
 msgstr "数据库管理"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:380
 msgid "Delete"
 msgstr "删除"
 
@@ -183,11 +235,11 @@
 msgid "Dismiss"
 msgstr "关闭"
 
-#: share/web/templates/__jifty/admin/index.html:28 share/web/templates/__jifty/admin/model/dhandler:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:458 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:486 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:56
 msgid "Done?"
 msgstr "已完成?"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:40 share/web/templates/__jifty/halo:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:388 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
 msgid "Edit"
 msgstr "编辑"
 
@@ -196,77 +248,190 @@
 msgid "Edit %1"
 msgstr "编辑 %1"
 
-#: share/web/templates/dhandler:7
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:23 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:32
+msgid "Email"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+msgid "Email address"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+msgid "Email address confirmed?"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1158
+msgid "Foo cannot contain -, *, +, or ?."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1152
+msgid "Foo cannot contain uppercase letters."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1136
+msgid "Foo values are always in lowercase."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:27
+msgid "For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:138 share/web/templates/dhandler:7
 msgid "Go back home..."
 msgstr "回到首页..."
 
-#: share/web/templates/_elements/sidebar:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
+msgid "Hashed Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:44
+msgid "Head on back home"
+msgstr ""
+
+#: lib/Jifty/I18N.pm:19 lib/Jifty/I18N.pm:23
+#. ('World')
+msgid "Hello, %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
 #. ($u->$method()
 msgid "Hiya, %1."
 msgstr "您好,%1。"
 
-#: share/web/templates/_elements/nav:3
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
 msgid "Home"
 msgstr "首页"
 
-#: share/web/templates/__jifty/admin/index.html:1
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+msgid "How should I display your name to other users?"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1090
+msgid "I changed $field for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:64
+msgid "I'm not sure how this happened."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
+msgid "Internal error"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
+msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
+msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+msgid "It looks like you're already confirmed."
+msgstr ""
+
+#:
 msgid "Jifty Administrative Console"
 msgstr "Jifty 管理界面"
 
-#: share/web/templates/__jifty/online_docs/toc.html:6
+#:
 msgid "Jifty Developer Documentation Online"
 msgstr "Jifty 在线开发文档"
 
-#: share/web/templates/__jifty/online_docs/content.html:6
+#:
 msgid "Jifty Pod Online"
 msgstr "Jifty 在线 POD 文件"
 
-#: share/web/templates/_elements/wrapper:18
+#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
 msgid "Loading..."
 msgstr "正在加载..."
 
-#: share/web/templates/__jifty/admin/model/dhandler:9
-#. ($object_type)
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:106
+msgid "Login"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+msgid "Login with a password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+msgid "Login!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:123
+msgid "Logout"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+msgid "Lost your password?"
+msgstr ""
+
+#:
 msgid "Manage %1 records"
 msgstr "管理 %1 记录"
 
-#: share/web/templates/__jifty/admin/model/dhandler:11
+#:
 msgid "Manage records:"
 msgstr "管理记录:"
 
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:46 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:473
+#. ($object_type)
+msgid "Manage records: [_1]"
+msgstr ""
+
 #: share/web/templates/__jifty/error/mason_internal_error:1
 msgid "Mason error"
 msgstr "Mason 系统错误"
 
-#: share/web/templates/__jifty/admin/index.html:9
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:429
 msgid "Models"
 msgstr "模型"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:113
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:81
+msgid "New password"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:172
 msgid "Next Page"
 msgstr "下一页"
 
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+msgid "Nickname"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+msgid "No account yet? It's quick and easy. "
+msgstr ""
+
 #: lib/Jifty/Action/Record/Search.pm:130
 msgid "No field contains"
 msgstr "没有字段包含"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:85
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:139
 msgid "No items found"
 msgstr "未找到记录"
 
-#: lib/Jifty/Web.pm:300
+#: lib/Jifty/Web.pm:302
 msgid "No request to handle"
 msgstr "没有可处理的请求"
 
-#: share/web/templates/__jifty/online_docs/index.html:5
+#:
 msgid "Online Documentation"
 msgstr "线上文件"
 
-#: share/web/templates/_elements/nav:6
+#: lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm:26
 msgid "Online docs"
 msgstr "线上文件"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:80
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:134
 #. ($page, $collection->pager->last_page)
 msgid "Page %1 of %2"
 msgstr "第 %1 页, 共 %2 页"
@@ -279,24 +444,48 @@
 msgid "Parent"
 msgstr "上层组件"
 
-#: lib/Jifty/Record.pm:264 lib/Jifty/Record.pm:343 lib/Jifty/Record.pm:68
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+msgid "Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+msgid "Passwords need to be at least six characters long"
+msgstr ""
+
+#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
 msgid "Permission denied"
 msgstr "权限不足"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:108
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:66
+msgid "Please email us!"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:163
 msgid "Previous Page"
 msgstr "上一页"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
+msgid "Really, really sorry."
+msgstr ""
+
 #:
 msgid "Record created"
 msgstr "成功建立记录."
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:37
+msgid "Remember me?"
+msgstr ""
+
 #: share/web/templates/__jifty/halo:69
 #. ($frame->{'render_time'})
 msgid "Rendered in %1s"
 msgstr "页面绘制时间: %1 秒"
 
-#: share/web/templates/__jifty/admin/action/dhandler:20
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:78
+msgid "Reset lost password"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:53
 msgid "Run the action"
 msgstr "执行动作"
 
@@ -304,58 +493,120 @@
 msgid "SQL Statements"
 msgstr "SQL 陈述式"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:21
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:327
 msgid "Save"
 msgstr "保存"
 
-#: share/web/templates/__jifty/online_docs/content.html:50
+#:
 msgid "Schema"
 msgstr "模式"
 
-#: share/web/templates/__jifty/admin/fragments/list/search:18
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:304
 msgid "Search"
 msgstr "查找"
 
-#: share/web/templates/dhandler:1
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:119
+msgid "Send"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+msgid "Send a link to reset your password"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:109 lib/Jifty/Plugin/Authentication/Password/View.pm:114
+msgid "Send a password reminder"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:111
+msgid "Sign up"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+msgid "Sign up for an account!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+msgid "Signup"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+#. ($msg)
+msgid "Something bad happened and we couldn't create your account: %1"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:149
+msgid "Something went awry"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:124 share/web/templates/dhandler:1
 msgid "Something's not quite right"
 msgstr "系统错误"
 
-#: share/web/templates/__jifty/online_docs/index.html:16 share/web/templates/__jifty/online_docs/index.html:18
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:132
+msgid "Sorry about this."
+msgstr ""
+
+#:
 msgid "Table of Contents"
 msgstr "目录"
 
-#: lib/Jifty/Action.pm:876
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#. ($new_email)
+msgid "That %1 doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action.pm:878
 msgid "That doesn't look like a correct value"
 msgstr "字段格式错误."
 
-#: lib/Jifty/Action/Record.pm:248
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+msgid "That doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action/Record.pm:249
 msgid "That doesn't look right, but I don't know why"
 msgstr "字段内容错误."
 
-#: lib/Jifty/Action/Record.pm:180
+#: lib/Jifty/Action/Record.pm:181
 msgid "The passwords you typed didn't match each other"
 msgstr "两组口令不匹配."
 
-#: lib/Jifty/Web.pm:363
+#: lib/Jifty/Web.pm:365
 msgid "There was an error completing the request.  Please try again later."
 msgstr "系统执行错误, 请稍候再试."
 
-#: share/web/templates/__jifty/admin/index.html:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:81
+msgid "There was an error setting your password."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:37
+msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:419
 msgid "This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records."
 msgstr "您可利用此界面来管理数据库的内容. 请点选表格名称, 进行增删及编辑."
 
-#: share/web/templates/__jifty/admin/index.html:7
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:425
 msgid "To disable this administrative console, add \"AdminMode: 0\" under the \"framework:\" settings in the config file (etc/config.yml)."
 msgstr "如果想停用管理界面, 请在配置文件 (etc/config.yml) 的 \"framework:\" 配置项内加上 \"AdminMode: 0\" 即可."
 
-#: share/web/templates/__jifty/admin/fragments/list/list:72
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:127
 msgid "Toggle search"
 msgstr "切换搜寻画面"
 
-#: share/web/templates/__jifty/error/mason_internal_error:6
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:173 share/web/templates/__jifty/error/mason_internal_error:6
 msgid "Try again"
 msgstr "重试一下"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+msgid "Try again later. We're really, really sorry."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:53
+msgid "Type that again?"
+msgstr ""
+
 #: lib/Jifty/Action/Record/Update.pm:156
 msgid "Updated"
 msgstr "成功更新项目."
@@ -364,35 +615,120 @@
 msgid "Variables"
 msgstr "变項"
 
-#: share/web/templates/index.html:1
+#: lib/Jifty.pm:27
+msgid "W00t"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
+msgid "We've sent a confirmation message to your email box."
+msgstr ""
+
+#: lib/Jifty/I18N.pm:31
+#. ('Bob', 'World')
+msgid "Welcome %1 to the %2"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#. ($user->name)
+msgid "Welcome back, %1."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:40
+#. ($appname)
+msgid "Welcome to %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2. "
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
 msgid "Welcome to your new Jifty application"
 msgstr "欢迎光临您的崭新的 Jifty 应用程序"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
+msgid "You don't exist."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:130
+msgid "You got to a page that we don't think exists."
+msgstr ""
+
 #: share/web/templates/dhandler:5
 msgid "You got to a page that we don't think exists.  Anyway, the software has logged this error. Sorry about this."
 msgstr "抱歉, 此页面不存在, 系统已留下纪录."
 
-#: lib/Jifty/Action.pm:863
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:44
+msgid "You have already confirmed your account."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:98
+msgid "You lost your password. A link to reset it will be sent to the following email address:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:115
+msgid "You lost your password. A reminder will be send to the following mail:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
+msgid "You may have mistyped your email address or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
+msgid "You may have mistyped your email or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Action.pm:865
 msgid "You need to fill in this field"
 msgstr "此字段非空."
 
-#: share/web/templates/index.html:3
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
 #. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
 msgid "You said you wanted a pony. (Source %1)"
 msgstr "您可不正是想要一匹小马吗? (参见 %1)"
 
-#: share/web/templates/_elements/sidebar:7
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+msgid "You're already logged in."
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
 msgid "You're not currently signed in."
 msgstr "您目前尚未登录."
 
-#: share/web/templates/__jifty/admin/fragments/list/header:22
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
+msgid "Your browser can remember your login for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:87
+msgid "Your password has been reset.  Welcome back."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+msgid "Your password should be at least six characters"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:246
 msgid "asc"
 msgstr "升序"
 
-#: share/web/templates/__jifty/admin/fragments/list/header:41
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:264
 msgid "desc"
 msgstr "降序"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:31
+msgid "email address"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:46
+msgid "for now, and try to forget that we let you down."
+msgstr ""
+
 #: lib/Jifty/Manual/PageRegions.pod:188
 msgid "text of the link"
 msgstr "连结文字"
@@ -400,3 +736,11 @@
 #: lib/Jifty/Manual/PageRegions.pod:225
 msgid "text of the link that hides"
 msgstr "隐藏连结文字"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:37
+msgid "type your password again"
+msgstr ""
+
+#: lib/Jifty/Action.pm:1050
+msgid "warning"
+msgstr ""

Modified: jifty/branches/virtual-models/share/po/zh_tw.po
==============================================================================
--- jifty/branches/virtual-models/share/po/zh_tw.po	(original)
+++ jifty/branches/virtual-models/share/po/zh_tw.po	Mon May  7 16:28:32 2007
@@ -14,10 +14,55 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmLostPassword.pm:38
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"request to reset your password for %1.\n"
+"\n"
+"If you don't want to reset your password just ignore this message.\n"
+"\n"
+"To reset your password, click on the link below:\n"
+"\n"
+"%2\n"
+msgstr ""
+"\n"
+"您 (或自稱是您的某人) 要求重設您在 %1 的密碼.\n"
+"\n"
+"如果您不想重設密碼, 請忽略這封信.\n"
+"\n"
+"若要重設密碼, 請點擊以下鏈結:\n"
+"\n"
+"%2\n"
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:41
+#. ($appname,$confirm_url)
+msgid ""
+"\n"
+"You're getting this message because you (or somebody claiming to be you)\n"
+"wants to use %1. \n"
+"\n"
+"We need to make sure that we got your email address right.  Click on the link below to get started:\n"
+"\n"
+"%2\n"
+msgstr ""
+"\n"
+"您 (或自稱是您的某人) 在 %1 申請註冊.\n"
+"\n"
+"請點擊以下鏈結, 以確認您的電郵帳號:\n"
+"\n"
+"%2\n"
+
 #: lib/Jifty/Action/Record/Search.pm:125
 msgid "!=>< allowed"
 msgstr "可使用 !=>< 符號"
 
+#: lib/Jifty/Notification.pm:94
+#. ($appname, Jifty->config->framework('AdminEmail')
+msgid "%1 <%2>"
+msgstr "%1 <%2>"
+
 #: lib/Jifty/Action/Record/Search.pm:115
 #. ($label)
 msgid "%1 after"
@@ -33,7 +78,7 @@
 msgid "%1 contains"
 msgstr "%1 包含"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:87
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:141
 #. ($collection-> count)
 msgid "%1 entries"
 msgstr "共 %1 筆"
@@ -93,23 +138,32 @@
 msgid "(any)"
 msgstr "(不限)"
 
-#: lib/Jifty/Web/Form/.Field.pm.swp:44 lib/Jifty/Web/Form/Field.pm:549
-msgid "@{[$self->current_value]}"
-msgstr ""
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:58
+msgid ". Your email address has now been confirmed."
+msgstr ". 現已成功確認您的電郵地址."
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:96
+msgid "A link to reset your password has been sent to your email account."
+msgstr "重設密碼的通知信已送到您的電郵地址."
+
+#: lib/Jifty/Notification.pm:96
+#. ($appname)
+msgid "A notification from %1!"
+msgstr "%1 捎來的訊息!"
 
-#: share/web/templates/__jifty/admin/index.html:19
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:443
 msgid "Actions"
 msgstr "操作"
 
-#: share/web/templates/_elements/nav:5
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
 msgid "Administration"
 msgstr "管理介面"
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
 msgid "Administration mode is enabled."
 msgstr "系統管理模式開啟中."
 
-#: share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
 msgid "Alert"
 msgstr "請注意"
 
@@ -121,11 +175,19 @@
 msgid "Any field contains"
 msgstr "任意欄位包含"
 
-#: share/web/templates/__jifty/admin/action/dhandler:25 share/web/templates/__jifty/admin/model/dhandler:21
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:131
+msgid "Anyway, the software has logged this error."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+msgid "Authentication token"
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:489 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:59
 msgid "Back to the admin console"
 msgstr "回到管理介面"
 
-#: share/web/templates/__jifty/admin/index.html:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:461
 msgid "Back to the application"
 msgstr "回到應用程式"
 
@@ -138,7 +200,7 @@
 msgid "Calendar"
 msgstr "日曆"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:338
 msgid "Cancel"
 msgstr "取消"
 
@@ -150,11 +212,15 @@
 msgid "Close window"
 msgstr "關閉視窗"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:31
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:382
 msgid "Confirm delete?"
 msgstr "是否確定刪除?"
 
-#: share/web/templates/__jifty/admin/fragments/list/new_item:25
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+msgid "Confirmation resent."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:213
 msgid "Create"
 msgstr "建立"
 
@@ -167,11 +233,11 @@
 msgid "Created"
 msgstr "成功建立項目."
 
-#: share/web/templates/__jifty/admin/index.html:3
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:415
 msgid "Database Administration"
 msgstr "資料庫管理"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:29
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:380
 msgid "Delete"
 msgstr "刪除"
 
@@ -183,11 +249,11 @@
 msgid "Dismiss"
 msgstr "關閉"
 
-#: share/web/templates/__jifty/admin/index.html:28 share/web/templates/__jifty/admin/model/dhandler:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:458 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:486 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:56
 msgid "Done?"
 msgstr "設定完畢?"
 
-#: share/web/templates/__jifty/admin/fragments/list/view:40 share/web/templates/__jifty/halo:20
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:388 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
 msgid "Edit"
 msgstr "編輯"
 
@@ -196,77 +262,190 @@
 msgid "Edit %1"
 msgstr "編輯 %1"
 
-#: share/web/templates/dhandler:7
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:23 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:32
+msgid "Email"
+msgstr "電郵"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+msgid "Email address"
+msgstr "電郵地址"
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+msgid "Email address confirmed?"
+msgstr "已確認電郵地址?"
+
+#: lib/Jifty/Action.pm:1158
+msgid "Foo cannot contain -, *, +, or ?."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1152
+msgid "Foo cannot contain uppercase letters."
+msgstr ""
+
+#: lib/Jifty/Action.pm:1136
+msgid "Foo values are always in lowercase."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:27
+msgid "For one reason or another, you got to a web page that caused a bit of an error. And then you got to our 'basic' error handler. Which means we haven't written a pretty, easy to understand error message for you just yet. The message we do have is :"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:138 share/web/templates/dhandler:7
 msgid "Go back home..."
 msgstr "回首頁..."
 
-#: share/web/templates/_elements/sidebar:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
+msgid "Hashed Password"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:44
+msgid "Head on back home"
+msgstr "回首頁"
+
+#: lib/Jifty/I18N.pm:19 lib/Jifty/I18N.pm:23
+#. ('World')
+msgid "Hello, %1!"
+msgstr "%1 您好!"
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
 #. ($u->$method()
 msgid "Hiya, %1."
 msgstr "%1 您好."
 
-#: share/web/templates/_elements/nav:3
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
 msgid "Home"
 msgstr "首頁"
 
-#: share/web/templates/__jifty/admin/index.html:1
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+msgid "How should I display your name to other users?"
+msgstr "您在本系統的代號"
+
+#: lib/Jifty/Action.pm:1090
+msgid "I changed $field for you"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:64
+msgid "I'm not sure how this happened."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
+msgid "Internal error"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
+msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
+msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+msgid "It looks like you're already confirmed."
+msgstr ""
+
+#:
 msgid "Jifty Administrative Console"
 msgstr "Jifty 管理介面"
 
-#: share/web/templates/__jifty/online_docs/toc.html:6
+#:
 msgid "Jifty Developer Documentation Online"
 msgstr "Jifty 線上開發文件"
 
-#: share/web/templates/__jifty/online_docs/content.html:6
+#:
 msgid "Jifty Pod Online"
 msgstr "Jifty 線上 POD 文件"
 
-#: share/web/templates/_elements/wrapper:18
+#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
 msgid "Loading..."
 msgstr "請稍候..."
 
-#: share/web/templates/__jifty/admin/model/dhandler:9
-#. ($object_type)
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:106
+msgid "Login"
+msgstr "登入"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+msgid "Login with a password"
+msgstr "使用密碼登入"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+msgid "Login!"
+msgstr "登入!"
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:123
+msgid "Logout"
+msgstr "登出"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+msgid "Lost your password?"
+msgstr "忘記密碼了?"
+
+#:
 msgid "Manage %1 records"
 msgstr "管理 %1 記錄"
 
-#: share/web/templates/__jifty/admin/model/dhandler:11
+#:
 msgid "Manage records:"
 msgstr "管理記錄:"
 
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:46 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:473
+#. ($object_type)
+msgid "Manage records: [_1]"
+msgstr ""
+
 #: share/web/templates/__jifty/error/mason_internal_error:1
 msgid "Mason error"
 msgstr "Mason 系統錯誤"
 
-#: share/web/templates/__jifty/admin/index.html:9
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:429
 msgid "Models"
 msgstr "模型"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:113
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:81
+msgid "New password"
+msgstr "新的密碼"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:172
 msgid "Next Page"
 msgstr "下一頁"
 
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+msgid "Nickname"
+msgstr "暱稱"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+msgid "No account yet? It's quick and easy. "
+msgstr "還沒有註冊帳號嗎? "
+
 #: lib/Jifty/Action/Record/Search.pm:130
 msgid "No field contains"
 msgstr "沒有欄位包含"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:85
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:139
 msgid "No items found"
 msgstr "未找到記錄"
 
-#: lib/Jifty/Web.pm:300
+#: lib/Jifty/Web.pm:302
 msgid "No request to handle"
 msgstr "沒有可處理的要求"
 
-#: share/web/templates/__jifty/online_docs/index.html:5
+#:
 msgid "Online Documentation"
 msgstr "線上文件"
 
-#: share/web/templates/_elements/nav:6
+#: lib/Jifty/Plugin/OnlineDocs/Dispatcher.pm:26
 msgid "Online docs"
 msgstr "線上文件"
 
-#: share/web/templates/__jifty/admin/fragments/list/list:80
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:134
 #. ($page, $collection->pager->last_page)
 msgid "Page %1 of %2"
 msgstr "第 %1 頁, 共 %2 頁"
@@ -279,24 +458,48 @@
 msgid "Parent"
 msgstr "上層元件"
 
-#: lib/Jifty/Record.pm:264 lib/Jifty/Record.pm:343 lib/Jifty/Record.pm:68
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+msgid "Password"
+msgstr "密碼"
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+msgid "Passwords need to be at least six characters long"
+msgstr "密碼至少需要有六個字"
+
+#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
 msgid "Permission denied"
 msgstr "權限不足."
 
-#: share/web/templates/__jifty/admin/fragments/list/list:108
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:66
+msgid "Please email us!"
+msgstr "請寫信通知我們!"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:163
 msgid "Previous Page"
 msgstr "上一頁"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
+msgid "Really, really sorry."
+msgstr "十二萬分抱歉."
+
 #:
 msgid "Record created"
 msgstr "成功建立項目."
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:37
+msgid "Remember me?"
+msgstr "記住我?"
+
 #: share/web/templates/__jifty/halo:69
 #. ($frame->{'render_time'})
 msgid "Rendered in %1s"
 msgstr "頁面繪製時間: %1 秒"
 
-#: share/web/templates/__jifty/admin/action/dhandler:20
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:78
+msgid "Reset lost password"
+msgstr "重設密碼"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:53
 msgid "Run the action"
 msgstr "執行動作"
 
@@ -304,58 +507,120 @@
 msgid "SQL Statements"
 msgstr "SQL 陳述式"
 
-#: share/web/templates/__jifty/admin/fragments/list/update:21
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:327
 msgid "Save"
 msgstr "儲存"
 
-#: share/web/templates/__jifty/online_docs/content.html:50
+#:
 msgid "Schema"
 msgstr "綱要"
 
-#: share/web/templates/__jifty/admin/fragments/list/search:18
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:304
 msgid "Search"
 msgstr "搜尋"
 
-#: share/web/templates/dhandler:1
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:119
+msgid "Send"
+msgstr "寄出"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+msgid "Send a link to reset your password"
+msgstr "寄送重設密碼的鏈結"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:109 lib/Jifty/Plugin/Authentication/Password/View.pm:114
+msgid "Send a password reminder"
+msgstr "重設密碼"
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:111
+msgid "Sign up"
+msgstr "註冊"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+msgid "Sign up for an account!"
+msgstr "現在就註冊!"
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+msgid "Signup"
+msgstr "註冊"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+#. ($msg)
+msgid "Something bad happened and we couldn't create your account: %1"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:149
+msgid "Something went awry"
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:124 share/web/templates/dhandler:1
 msgid "Something's not quite right"
 msgstr "系統錯誤"
 
-#: share/web/templates/__jifty/online_docs/index.html:16 share/web/templates/__jifty/online_docs/index.html:18
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:132
+msgid "Sorry about this."
+msgstr "非常抱歉."
+
+#:
 msgid "Table of Contents"
 msgstr "目錄"
 
-#: lib/Jifty/Action.pm:876
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#. ($new_email)
+msgid "That %1 doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action.pm:878
 msgid "That doesn't look like a correct value"
 msgstr "欄位格式錯誤."
 
-#: lib/Jifty/Action/Record.pm:248
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+msgid "That doesn't look like an email address."
+msgstr ""
+
+#: lib/Jifty/Action/Record.pm:249
 msgid "That doesn't look right, but I don't know why"
 msgstr "欄位內容錯誤."
 
-#: lib/Jifty/Action/Record.pm:180
+#: lib/Jifty/Action/Record.pm:181
 msgid "The passwords you typed didn't match each other"
 msgstr "兩組密碼不符合."
 
-#: lib/Jifty/Web.pm:363
+#: lib/Jifty/Web.pm:365
 msgid "There was an error completing the request.  Please try again later."
 msgstr "系統執行錯誤, 請稍候再試."
 
-#: share/web/templates/__jifty/admin/index.html:5
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:81
+msgid "There was an error setting your password."
+msgstr ""
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:37
+msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
+msgstr ""
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:419
 msgid "This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records."
 msgstr "您可利用此介面來管理資料庫的內容. 請點選表格名稱, 進行增刪及編輯."
 
-#: share/web/templates/__jifty/admin/index.html:7
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:425
 msgid "To disable this administrative console, add \"AdminMode: 0\" under the \"framework:\" settings in the config file (etc/config.yml)."
 msgstr "如欲停用管理介面, 請在設定檔 (etc/config.yml) 的 \"framework:\" 設定內加上 \"AdminMode: 0\" 即可."
 
-#: share/web/templates/__jifty/admin/fragments/list/list:72
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:127
 msgid "Toggle search"
 msgstr "切換搜尋畫面"
 
-#: share/web/templates/__jifty/error/mason_internal_error:6
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:173 share/web/templates/__jifty/error/mason_internal_error:6
 msgid "Try again"
 msgstr "再試一下"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:108
+msgid "Try again later. We're really, really sorry."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:53
+msgid "Type that again?"
+msgstr "請再輸入一次"
+
 #: lib/Jifty/Action/Record/Update.pm:156
 msgid "Updated"
 msgstr "成功更新項目."
@@ -364,34 +629,119 @@
 msgid "Variables"
 msgstr "變數"
 
-#: share/web/templates/index.html:1
+#: lib/Jifty.pm:27
+msgid "W00t"
+msgstr "喔耶"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
+msgid "We've sent a confirmation message to your email box."
+msgstr "系統已將確認信寄送到您的電郵信箱."
+
+#: lib/Jifty/I18N.pm:31
+#. ('Bob', 'World')
+msgid "Welcome %1 to the %2"
+msgstr "歡迎 %1 蒞臨 %2"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#. ($user->name)
+msgid "Welcome back, %1."
+msgstr "歡迎回來, %1."
+
+#: lib/Jifty/Plugin/Authentication/Password/Notification/ConfirmEmail.pm:40
+#. ($appname)
+msgid "Welcome to %1!"
+msgstr "歡迎光臨 %1!"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2."
+msgstr "歡迎光臨 %1, %2!"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
+#. (Jifty->config->framework('ApplicationName')
+msgid "Welcome to %1, %2. "
+msgstr "歡迎光臨 %1, %2. "
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
 msgid "Welcome to your new Jifty application"
 msgstr "歡迎光臨您嶄新的 Jifty 應用程式"
 
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
+msgid "You don't exist."
+msgstr "您不存在."
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:130
+msgid "You got to a page that we don't think exists."
+msgstr "此頁面不存在."
+
 #: share/web/templates/dhandler:5
 msgid "You got to a page that we don't think exists.  Anyway, the software has logged this error. Sorry about this."
 msgstr "抱歉, 此頁面不存在, 系統已留下紀錄."
 
-#: lib/Jifty/Action.pm:863
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:44
+msgid "You have already confirmed your account."
+msgstr "您已經確認過這個帳號了."
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:98
+msgid "You lost your password. A link to reset it will be sent to the following email address:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:115
+msgid "You lost your password. A reminder will be send to the following mail:"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
+msgid "You may have mistyped your email address or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
+msgid "You may have mistyped your email or password. Give it another shot."
+msgstr ""
+
+#: lib/Jifty/Action.pm:865
 msgid "You need to fill in this field"
 msgstr "此欄位不能留空."
 
-#: share/web/templates/index.html:3
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
 #. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
 msgid "You said you wanted a pony. (Source %1)"
 msgstr "您可不正是想要一匹小馬嗎? (參見 %1)"
 
-#: share/web/templates/_elements/sidebar:7
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+msgid "You're already logged in."
+msgstr "您已經登入了."
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
 msgid "You're not currently signed in."
 msgstr "您目前尚未登入."
 
-#: share/web/templates/__jifty/admin/fragments/list/header:22
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
+msgid "Your browser can remember your login for you"
+msgstr "下次開啟瀏覽器時, 是否保留您的登入狀態?"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:87
+msgid "Your password has been reset.  Welcome back."
+msgstr "成功重設您的密碼. 歡迎回來."
+
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+msgid "Your password should be at least six characters"
+msgstr "您的密碼必須至少有六個字"
+
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:246
 msgid "asc"
-msgstr "昇冪"
+msgstr "遞增"
 
-#: share/web/templates/__jifty/admin/fragments/list/header:41
+#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:264
 msgid "desc"
-msgstr "降冪"
+msgstr "遞減"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:31
+msgid "email address"
+msgstr "電郵地址"
+
+#: lib/Jifty/Plugin/ErrorTemplates/View.pm:46
+msgid "for now, and try to forget that we let you down."
+msgstr ""
 
 #: lib/Jifty/Manual/PageRegions.pod:188
 msgid "text of the link"
@@ -400,3 +750,11 @@
 #: lib/Jifty/Manual/PageRegions.pod:225
 msgid "text of the link that hides"
 msgstr "隱藏連結文字"
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:37
+msgid "type your password again"
+msgstr "請再次鍵入您的密碼"
+
+#: lib/Jifty/Action.pm:1050
+msgid "warning"
+msgstr ""

Modified: jifty/branches/virtual-models/share/web/static/css/forms.css
==============================================================================
--- jifty/branches/virtual-models/share/web/static/css/forms.css	(original)
+++ jifty/branches/virtual-models/share/web/static/css/forms.css	Mon May  7 16:28:32 2007
@@ -198,7 +198,7 @@
 }
 
 
-.selected {
+option.selected {
     background: #dddddd;
 }
 

Modified: jifty/branches/virtual-models/share/web/static/css/main.css
==============================================================================
--- jifty/branches/virtual-models/share/web/static/css/main.css	(original)
+++ jifty/branches/virtual-models/share/web/static/css/main.css	Mon May  7 16:28:32 2007
@@ -10,4 +10,5 @@
 @import "app.css";
 @import "autocomplete.css";
 @import "yui/calendar/calendar.css";
+ at import "yui/menu/menu.css";
 @import "notices.css";

Modified: jifty/branches/virtual-models/share/web/static/css/yui/calendar/calendar.css
==============================================================================
--- jifty/branches/virtual-models/share/web/static/css/yui/calendar/calendar.css	(original)
+++ jifty/branches/virtual-models/share/web/static/css/yui/calendar/calendar.css	Mon May  7 16:28:32 2007
@@ -1,191 +1,197 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-Version 0.12
-*/
-
-.yui-calcontainer {
-	position:relative;
-	padding:5px;
-	background-color:#F7F9FB;
-	border:1px solid #7B9EBD;
-	float:left;
-	overflow:hidden;
-}
-
-.yui-calcontainer iframe {
-	position:absolute;
-	border:none;
-	margin:0;padding:0;
-	left:-1px;
-	top:-1px;
-	z-index:0;
-	width:50em;
-	height:50em;
-}
-
-.yui-calcontainer.multi {
-	padding:0;
-}
-
-.yui-calcontainer.multi .groupcal {
-	padding:5px;
-	background-color:transparent;
-	z-index:1;
-	float:left;
-	position:relative;
-	border:none;
-}
-
-.yui-calcontainer .title {
-	font:100% sans-serif;
-	color:#000;
-	font-weight:bold;
-	margin-bottom:5px;
-	height:25px;
-	position:absolute;
-	top:3px;left:5px;
-	z-index:1;
-}
-
-.yui-calcontainer .close-icon {
-	position:absolute;
-	right:3px;
-	top:3px;
-	border:none;
-	z-index:1;
-}
-
-/* Calendar element styles */
-
-.yui-calendar {
-	font:100% sans-serif;
-	text-align:center;
-	border-spacing:0;
-	border-collapse:separate;
-	position:relative;
-}
-
-.yui-calcontainer.withtitle {
-	padding-top:1.5em;
-}
-
-.yui-calendar .calnavleft {
-	position:absolute;
-	background-repeat:no-repeat;
-	cursor:pointer;
-	top:2px;
-	bottom:0;
-	width:9px;
-	height:12px;   
-	left:2px;
-	z-index:1;
-}
-
-.yui-calendar .calnavright {
-	position:absolute;
-	background-repeat:no-repeat;
-	cursor:pointer;
-	top:2px;
-	bottom:0;
-	width:9px;
-	height:12px;  
-	right:2px;
-	z-index:1;
-}
-
-.yui-calendar td.calcell {
-	padding:.1em .2em;
-	border:1px solid #E0E0E0;
-	text-align:center;
-}
-
-.yui-calendar td.calcell a {
-	color:#003DB8;
-	text-decoration:none;
-}
-
-.yui-calendar td.calcell.today {
-	border:1px solid #000;
-}
-
-.yui-calendar td.calcell.oom {
-	cursor:default;
-	color:#999;
-	background-color:#EEE;
-	border:1px solid #E0E0E0;
-}
-
-.yui-calendar td.calcell.selected {
-	color:#003DB8;
-	background-color:#FFF19F;
-	border:1px solid #FF9900;
-}
-
-.yui-calendar td.calcell.calcellhover {
-	cursor:pointer;
-	color:#FFF;
-	background-color:#FF9900;
-	border:1px solid #FF9900;
-}
-
-.yui-calendar td.calcell.calcellhover a {
-	color:#FFF;
-}
-
-.yui-calendar td.calcell.restricted {
-	text-decoration:line-through;
-}
-
-.yui-calendar td.calcell.previous {
-	color:#CCC;
-}
-
-.yui-calendar td.calcell.highlight1 { background-color:#CCFF99; }
-.yui-calendar td.calcell.highlight2 { background-color:#99CCFF; }
-.yui-calendar td.calcell.highlight3 { background-color:#FFCCCC; }
-.yui-calendar td.calcell.highlight4 { background-color:#CCFF99; }
-
-.yui-calendar .calhead {
-	border:1px solid #E0E0E0;
-	vertical-align:middle;
-	background-color:#FFF;
-}
-
-.yui-calendar .calheader {
-	position:relative;
-	width:100%;
-	text-align:center;
-}
-
-.yui-calendar .calheader img {
-	border:none;
-}
-
-.yui-calendar .calweekdaycell {
-	color:#666;
-	font-weight:normal;
-	text-align:center;
-	width:1.5em;
-}
-
-.yui-calendar .calfoot {
-	background-color:#EEE;
-}
-
-.yui-calendar .calrowhead, .yui-calendar .calrowfoot {
-	color:#666;
-	font-size:9px;
-	font-style:italic;
-	font-weight:normal;
-	width:15px;
-}
-
-.yui-calendar .calrowhead {
-	border-right-width:2px;
-}
-
-/*Specific changes for calendar running under fonts/reset */
-.yui-calendar a:hover {background:inherit;}
-p#clear {clear:left; padding-top:10px;}
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+.yui-calcontainer {
+	position:relative;
+	padding:5px;
+	background-color:#F7F9FB;
+	border:1px solid #7B9EBD;
+	float:left;
+	overflow:hidden;
+}
+
+.yui-calcontainer iframe {
+	position:absolute;
+	border:none;
+	margin:0;padding:0;
+	left:-1px;
+	top:-1px;
+	z-index:0;
+	width:50em;
+	height:50em;
+}
+
+.yui-calcontainer.multi {
+	padding:0;
+}
+
+.yui-calcontainer.multi .groupcal {
+	padding:5px;
+	background-color:transparent;
+	z-index:1;
+	float:left;
+	position:relative;
+	border:none;
+}
+
+.yui-calcontainer .title {
+	font:100% sans-serif;
+	color:#000;
+	font-weight:bold;
+	margin-bottom:5px;
+	height:25px;
+	position:absolute;
+	top:3px;left:5px;
+	z-index:1;
+}
+
+.yui-calcontainer .close-icon {
+	position:absolute;
+	right:3px;
+	top:3px;
+	border:none;
+	z-index:1;
+}
+
+.yui-calcontainer .calclose {
+	background: url("calx.gif") no-repeat;
+	width:17px;
+	height:13px;
+	cursor:pointer;	
+}
+
+/* Calendar element styles */
+
+.yui-calendar {
+	font:100% sans-serif;
+	text-align:center;
+	border-spacing:0;
+	border-collapse:separate;
+	position:relative;
+}
+
+.yui-calcontainer.withtitle {
+	padding-top:1.5em;
+}
+
+.yui-calendar .calnavleft {
+	position:absolute;
+	cursor:pointer;
+	top:2px;
+	bottom:0;
+	width:9px;
+	height:12px;   
+	left:2px;
+	z-index:1;
+	background: url("callt.gif") no-repeat;
+}
+
+.yui-calendar .calnavright {
+	position:absolute;
+	cursor:pointer;
+	top:2px;
+	bottom:0;
+	width:9px;
+	height:12px;
+	right:2px;
+	z-index:1;
+	background: url("calrt.gif") no-repeat;
+}
+
+.yui-calendar td.calcell {
+	padding:.1em .2em;
+	border:1px solid #E0E0E0;
+	text-align:center;
+}
+
+.yui-calendar td.calcell a {
+	color:#003DB8;
+	text-decoration:none;
+}
+
+.yui-calendar td.calcell.today {
+	border:1px solid #000;
+}
+
+.yui-calendar td.calcell.oom {
+	cursor:default;
+	color:#999;
+	background-color:#EEE;
+	border:1px solid #E0E0E0;
+}
+
+.yui-calendar td.calcell.selected {
+	color:#003DB8;
+	background-color:#FFF19F;
+	border:1px solid #FF9900;
+}
+
+.yui-calendar td.calcell.calcellhover {
+	cursor:pointer;
+	color:#FFF;
+	background-color:#FF9900;
+	border:1px solid #FF9900;
+}
+
+.yui-calendar td.calcell.calcellhover a {
+	color:#FFF;
+}
+
+.yui-calendar td.calcell.restricted {
+	text-decoration:line-through;
+}
+
+.yui-calendar td.calcell.previous {
+	color:#CCC;
+}
+
+.yui-calendar td.calcell.highlight1 { background-color:#CCFF99; }
+.yui-calendar td.calcell.highlight2 { background-color:#99CCFF; }
+.yui-calendar td.calcell.highlight3 { background-color:#FFCCCC; }
+.yui-calendar td.calcell.highlight4 { background-color:#CCFF99; }
+
+.yui-calendar .calhead {
+	border:1px solid #E0E0E0;
+	vertical-align:middle;
+	background-color:#FFF;
+}
+
+.yui-calendar .calheader {
+	position:relative;
+	width:100%;
+	text-align:center;
+}
+
+.yui-calendar .calheader img {
+	border:none;
+}
+
+.yui-calendar .calweekdaycell {
+	color:#666;
+	font-weight:normal;
+	text-align:center;
+	width:1.5em;
+}
+
+.yui-calendar .calfoot {
+	background-color:#EEE;
+}
+
+.yui-calendar .calrowhead, .yui-calendar .calrowfoot {
+	color:#666;
+	font-size:9px;
+	font-style:italic;
+	font-weight:normal;
+	width:15px;
+}
+
+.yui-calendar .calrowhead {
+	border-right-width:2px;
+}
+
+/* Specific changes for calendar running under fonts/reset */
+.yui-calendar .calbody a:hover {background:inherit;}
+p#clear {clear:left; padding-top:10px;}

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/map.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menu.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/share/web/static/css/yui/menu/menu.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,401 @@
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/* Menu styles */
+
+div.yuimenu {
+
+    background-color:#f6f7ee;
+    border:solid 1px #c4c4be;
+    padding:1px;
+    
+}
+
+/* Submenus are positioned absolute and hidden by default */
+
+div.yuimenu div.yuimenu,
+div.yuimenubar div.yuimenu {
+
+    position:absolute;
+    visibility:hidden;
+
+}
+
+/* MenuBar Styles */
+
+div.yuimenubar {
+
+    background-color:#f6f7ee;
+    
+}
+
+/*
+    Applying a width triggers "haslayout" in IE so that the module's
+    body clears its floated elements
+*/
+div.yuimenubar div.bd {
+
+    width:100%;
+
+}
+
+/*
+    Clear the module body for other browsers
+*/
+div.yuimenubar div.bd:after {
+
+    content:'.';
+    display:block;
+    clear:both;
+    visibility:hidden;
+    height:0;
+
+}
+
+/* Matches the group title (H6) inside a Menu or MenuBar instance */
+
+div.yuimenu h6,
+div.yuimenubar h6 { 
+
+    font-size:100%;
+    font-weight:normal;    
+    margin:0;
+    border:solid 1px #c4c4be;
+    color:#b9b9b9;    
+
+}
+
+div.yuimenubar h6 {
+
+    float:left;
+    display:inline; /* Prevent margin doubling in IE */
+    padding:4px 12px;
+    border-width:0 1px 0 0;
+    
+}
+
+div.yuimenu h6 {
+
+    float:none;
+    display:block;
+    border-width:1px 0 0 0;
+    padding:5px 10px 0 10px;
+
+}
+
+/* Matches the UL inside a Menu or MenuBar instance */
+
+div.yuimenubar ul {
+
+    list-style-type:none;
+    margin:0;
+    padding:0;
+
+}
+
+div.yuimenu ul {
+
+    list-style-type:none;
+    border:solid 1px #c4c4be;
+    border-width:1px 0 0 0;
+    margin:0;
+    padding:10px 0;
+
+}
+
+div.yuimenu ul.first-of-type, 
+div.yuimenu ul.hastitle,
+div.yuimenu h6.first-of-type {
+
+    border-width:0;
+
+}
+
+/*
+    Styles for the menu's header and footer elements that are used as controls 
+    to scroll the menu's body element when the menu's height exceeds the 
+    value of the "maxheight" configuration property.
+*/
+
+div.yuimenu div.topscrollbar,
+div.yuimenu div.bottomscrollbar {
+
+    height:16px;
+    background-image:url(map.gif);
+    background-repeat:no-repeat;
+
+}
+
+
+div.yuimenu div.topscrollbar {
+
+    background-image:url(map.gif);
+    background-position:center -72px;
+
+}
+
+
+div.yuimenu div.topscrollbar_disabled {
+
+    background-image:url(map.gif);
+    background-position:center -88px;
+
+}
+
+
+div.yuimenu div.bottomscrollbar {
+
+    background-image:url(map.gif);
+    background-position:center -104px;
+
+}
+
+
+div.yuimenu div.bottomscrollbar_disabled {
+
+    background-image:url(map.gif);
+    background-position:center -120px;
+
+}
+
+
+/* MenuItem and MenuBarItem styles */
+
+div.yuimenu li,
+div.yuimenubar li {
+
+    font-size:85%;
+    cursor:pointer;
+    cursor:hand;
+    white-space:nowrap;
+    text-align:left;
+
+}
+
+div.yuimenu li.yuimenuitem {
+
+    padding:2px 24px;
+    
+}
+
+div.yuimenu li li,
+div.yuimenubar li li {
+
+    font-size:100%;
+
+}
+
+
+/* Matches the help text for a menu item */
+
+div.yuimenu li.hashelptext em.helptext {
+
+    font-style:normal;
+    margin:0 0 0 40px;
+
+}
+
+div.yuimenu li a,
+div.yuimenubar li a {
+    
+    /*
+        "zoom:1" triggers "haslayout" in IE to ensure that the mouseover and 
+        mouseout events bubble to the parent LI in IE.
+    */
+    zoom:1;
+    color:#000;
+    text-decoration:none;
+    
+}
+
+div.yuimenu li.hassubmenu,
+div.yuimenu li.hashelptext {
+
+    text-align:right;
+
+}
+
+div.yuimenu li.hassubmenu a.hassubmenu,
+div.yuimenu li.hashelptext a.hashelptext {
+
+    /*
+        Need to apply float immediately for IE or help text will jump to the 
+        next line 
+    */
+
+    *float:left;
+    *display:inline; /* Prevent margin doubling in IE */
+    text-align:left;
+
+}
+
+div.yuimenu.visible li.hassubmenu a.hassubmenu, 
+div.yuimenu.visible li.hashelptext a.hashelptext {
+
+    /*
+        Apply the float only when the menu is visible to prevent the help
+        text from wrapping to the next line in Opera.
+    */
+
+    float:left;
+
+}
+
+
+/* Matches selected menu items */
+
+div.yuimenu li.selected,
+div.yuimenubar li.selected {
+
+    background-color:#8c8ad0;
+
+}
+
+div.yuimenu li.selected a.selected,
+div.yuimenubar li.selected a.selected {
+
+    text-decoration:underline;
+
+}
+
+div.yuimenu li.selected a.selected,
+div.yuimenu li.selected em.selected, 
+div.yuimenubar li.selected a.selected {
+
+    color:#fff;
+
+}
+
+
+/* Matches disabled menu items */
+
+div.yuimenu li.disabled, 
+div.yuimenubar li.disabled {
+
+    cursor:default;
+
+}
+
+div.yuimenu li.disabled a.disabled,
+div.yuimenu li.disabled em.disabled,
+div.yuimenubar li.disabled a.disabled {
+
+    color:#b9b9b9;
+    cursor:default;
+    
+}
+
+div.yuimenubar li.yuimenubaritem {
+
+    float:left;
+    display:inline; /* Prevent margin doubling in IE */
+    border-width:0 0 0 1px;
+    border-style:solid;
+    border-color:#c4c4be;
+    padding:4px 24px;
+    margin:0;
+
+}
+
+div.yuimenubar li.yuimenubaritem.first-of-type {
+
+    border-width:0;
+
+}
+
+
+/* Styles for the the submenu indicator for menu items */
+
+div.yuimenu li.hassubmenu em.submenuindicator, 
+div.yuimenubar li.hassubmenu em.submenuindicator {
+
+    display:-moz-inline-box; /* Mozilla */
+    display:inline-block; /* IE, Opera and Safari */
+    vertical-align:middle;
+    height:8px;
+    width:8px;
+    text-indent:9px;
+    font:0/0 arial;
+    overflow:hidden;
+    background-image:url(map.gif);
+    background-repeat:no-repeat;
+
+}
+
+div.yuimenubar li.hassubmenu em.submenuindicator {
+
+    background-position:0 -24px;
+    margin:0 0 0 10px;
+
+}
+
+div.yuimenubar li.hassubmenu em.submenuindicator.selected {
+
+    background-position:0 -32px;
+
+}
+
+div.yuimenubar li.hassubmenu em.submenuindicator.disabled {
+
+    background-position:0 -40px;
+
+}
+
+div.yuimenu li.hassubmenu em.submenuindicator {
+
+    background-position:0 0;
+    margin:0 -16px 0 10px;
+
+}
+
+div.yuimenu li.hassubmenu em.submenuindicator.selected {
+
+    background-position:0 -8px;
+
+}
+
+div.yuimenu li.hassubmenu em.submenuindicator.disabled {
+
+    background-position:0 -16px;
+
+}
+
+
+/* Styles for a menu item's "checked" state */
+
+div.yuimenu li.checked {
+
+    position:relative;
+
+}
+
+div.yuimenu li.checked em.checkedindicator {
+
+    height:8px;
+    width:8px;
+    text-indent:9px;
+    overflow:hidden;
+    background-image:url(map.gif);
+    background-position:0 -48px;
+    background-repeat:no-repeat;
+    position:absolute;
+    left:6px;
+    _left:-16px; /* Underscore hack b/c this is for IE 6 only */
+    top:.5em;
+
+}
+
+div.yuimenu li.checked em.checkedindicator.selected {
+
+    background-position:0 -56px;
+
+}
+
+div.yuimenu li.checked em.checkedindicator.disabled {
+
+    background-position:0 -64px;
+
+}
\ No newline at end of file

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarodwn8_dim_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarodwn8_hov_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarodwn8_nrm_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarorght8_dim_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarorght8_hov_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuarorght8_nrm_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuaroup8_dim_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuaroup8_nrm_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuchk8_dim_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuchk8_hov_1.gif
==============================================================================
Binary file. No diff available.

Added: jifty/branches/virtual-models/share/web/static/css/yui/menu/menuchk8_nrm_1.gif
==============================================================================
Binary file. No diff available.

Modified: jifty/branches/virtual-models/share/web/static/css/yui/tabview/border_tabs.css
==============================================================================
--- jifty/branches/virtual-models/share/web/static/css/yui/tabview/border_tabs.css	(original)
+++ jifty/branches/virtual-models/share/web/static/css/yui/tabview/border_tabs.css	Mon May  7 16:28:32 2007
@@ -1,44 +1,54 @@
-.yui-navset .yui-nav li a, .yui-navset .yui-content {
-    border:1px solid #000;  /* label and content borders */
-}
-
-.yui-navset .yui-nav .selected a, .yui-navset .yui-nav a:hover, .yui-navset .yui-content {
-    background-color:#f6f7ee; /* active tab, tab hover, and content bgcolor */
-}
-
-.yui-navset-top .yui-nav .selected a {
-    border-bottom:0; /* no bottom border for active tab */
-    padding-bottom:1px; /* to match height of other tabs */
-}
-
-.yui-navset-top .yui-content {
-    margin-top:-1px; /* for active tab overlap */
-}
-
-.yui-navset-bottom .yui-nav .selected a {
-    border-top:0; /* no bottom border for active tab */
-    padding-top:1px; /* to match height of other tabs */
-}
-
-.yui-navset-bottom .yui-content {
-    margin-bottom:-1px; /* for active tab overlap */
-}
-
-.yui-navset-left .yui-nav li.selected a {
-    border-right:0; /* no bottom border for active tab */
-    padding-right:1px; /* to match height of other tabs */
-}
-
-.yui-navset-left .yui-content {
-    margin-left:-1px; /* for active tab overlap */
-}
-
-.yui-navset-right .yui-nav li.selected a {
-    border-left:0; /* no bottom border for active tab */
-    padding-left:1px; /* to match height of other tabs */
-}
-
-.yui-navset-right .yui-content {
-    margin-right:-1px; /* for active tab overlap */
-    *margin-right:0; /* except IE */
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+.yui-navset .yui-nav li a, .yui-navset .yui-content {
+    border:1px solid #000;  /* label and content borders */
+}
+
+.yui-navset .yui-nav .selected a, .yui-navset .yui-nav a:hover, .yui-navset .yui-content {
+    background-color:#f6f7ee; /* active tab, tab hover, and content bgcolor */
+}
+
+.yui-navset .yui-nav li em { padding:.5em; } /* tab padding */
+
+/* defaults to orientation "top" */
+.yui-navset .yui-nav .selected a {
+    border-bottom-width:0; /* no bottom border for active tab */
+    padding-bottom:1px; /* to match height of other tabs */
+}
+
+.yui-navset .yui-content {
+    margin-top:-1px; /* for active tab overlap */
+}
+
+/* overrides for other orientations */
+
+.yui-navset-bottom .yui-nav .selected a {
+    border-width:0 1px 1px; /* no top border for active tab */
+    padding:1px 0 0; /* to match height of other tabs */
+}
+
+.yui-navset-bottom .yui-content {
+    margin:0 0 -1px; /* for active tab overlap */
+}
+
+.yui-navset-left .yui-nav li.selected a {
+    border-width:1px 0 1px 1px; /* no right border for active tab */
+    padding:0 1px 0 0; /* to match width of other tabs */
+}
+
+.yui-navset-left .yui-content {
+    margin:0 0 0 -1px; /* for active tab overlap */
+}
+
+.yui-navset-right .yui-nav li.selected a {
+    border-width:1px 1px 1px 0; /* no left border for active tab */
+    padding:0 0 0 1px; /* to match width of other tabs */
+}
+
+.yui-navset-right .yui-content {
+    margin:0 -1px 0 0; /* for active tab overlap */
 }
\ No newline at end of file

Modified: jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabs.css
==============================================================================
--- jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabs.css	(original)
+++ jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabs.css	Mon May  7 16:28:32 2007
@@ -1,3 +1,5 @@
+/* XXX: It is a older CSS file, please use tabview.css instead */
+
 /* default space between tabs */
 .yui-navset-top .yui-nav li, .yui-navset-bottom .yui-nav li {
     margin-right:0.5em; /* horizontal tabs */

Added: jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabview.css
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/share/web/static/css/yui/tabview/tabview.css	Mon May  7 16:28:32 2007
@@ -0,0 +1,75 @@
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/* default space between tabs */
+.yui-navset .yui-nav li {
+    margin-right:0.5em; /* horizontal tabs */
+}
+.yui-navset-left .yui-nav li, .yui-navset-right .yui-nav li {
+    margin:0 0 0.5em; /* vertical tabs */
+}
+
+/* default width for side tabs */
+.yui-navset-left .yui-nav, .yui-navset-right .yui-nav { width:6em; }
+.yui-navset-left { padding-left:6em; } /* map to nav width */
+.yui-navset-right { padding-right:6em; } /* ditto */
+
+/* core */
+
+.yui-nav, .yui-nav li {
+    margin:0;
+    padding:0;
+    list-style:none;
+}
+.yui-navset li em { font-style:normal; }
+
+.yui-navset {
+    position:relative; /* contain absolute positioned tabs (left/right) */
+    zoom:1;
+}
+
+.yui-navset .yui-content { zoom:1; }
+
+.yui-navset .yui-nav li {
+    display:inline-block;
+    display:-moz-inline-stack;
+    *display:inline; /* IE */
+    vertical-align:bottom; /* safari: for overlap */
+    cursor:pointer; /* gecko: due to -moz-inline-stack on anchor */
+    zoom:1; /* IE: kill space between horizontal tabs */
+}
+
+.yui-navset-left .yui-nav li, .yui-navset-right .yui-nav li {
+    display:block;
+}
+
+.yui-navset .yui-nav a {
+    outline:0; /* gecko: keep from shifting */
+}
+
+.yui-navset .yui-nav a { position:relative; } /* IE: to allow overlap */
+
+.yui-navset .yui-nav li a {
+    display:block;
+    display:inline-block;
+    vertical-align:bottom; /* safari: for overlap */
+    zoom:1;
+}
+
+.yui-navset-left .yui-nav li a, .yui-navset-right .yui-nav li a {
+    display:block;
+}
+
+.yui-navset-bottom .yui-nav li a {
+    vertical-align:text-top; /* for inline overlap (reverse for Op border bug) */
+}
+
+.yui-navset .yui-nav li a em { display:block; }
+
+/* position left and right oriented tabs */
+.yui-navset-left .yui-nav, .yui-navset-right .yui-nav { position:absolute; z-index:1; }
+.yui-navset-left .yui-nav { left:0; }
+.yui-navset-right .yui-nav { right:0; }

Modified: jifty/branches/virtual-models/share/web/static/js/yui/calendar.js
==============================================================================
--- jifty/branches/virtual-models/share/web/static/js/yui/calendar.js	(original)
+++ jifty/branches/virtual-models/share/web/static/js/yui/calendar.js	Mon May  7 16:28:32 2007
@@ -1,4255 +1,4547 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version 0.12.0
-*/
-
-/**
-* Config is a utility used within an Object to allow the implementer to maintain a list of local configuration properties and listen for changes to those properties dynamically using CustomEvent. The initial values are also maintained so that the configuration can be reset at any given point to its initial state.
-* @class YAHOO.util.Config
-* @constructor
-* @param {Object}	owner	The owner Object to which this Config Object belongs
-*/
-YAHOO.util.Config = function(owner) {
-	if (owner) {
-		this.init(owner);
-	}
-};
-
-YAHOO.util.Config.prototype = {
-
-	/**
-	* Object reference to the owner of this Config Object
-	* @property owner
-	* @type Object
-	*/
-	owner : null,
-
-	/**
-	* Boolean flag that specifies whether a queue is currently being executed
-	* @property queueInProgress
-	* @type Boolean
-	*/
-	queueInProgress : false,
-
-
-	/**
-	* Validates that the value passed in is a Boolean.
-	* @method checkBoolean
-	* @param	{Object}	val	The value to validate
-	* @return	{Boolean}	true, if the value is valid
-	*/
-	checkBoolean: function(val) {
-		if (typeof val == 'boolean') {
-			return true;
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	* Validates that the value passed in is a number.
-	* @method checkNumber
-	* @param	{Object}	val	The value to validate
-	* @return	{Boolean}	true, if the value is valid
-	*/
-	checkNumber: function(val) {
-		if (isNaN(val)) {
-			return false;
-		} else {
-			return true;
-		}
-	}
-};
-
-
-/**
-* Initializes the configuration Object and all of its local members.
-* @method init
-* @param {Object}	owner	The owner Object to which this Config Object belongs
-*/
-YAHOO.util.Config.prototype.init = function(owner) {
-
-	this.owner = owner;
-
-	/**
-	* Object reference to the owner of this Config Object
-	* @event configChangedEvent
-	*/
-	this.configChangedEvent = new YAHOO.util.CustomEvent("configChanged");
-
-	this.queueInProgress = false;
-
-	/* Private Members */
-
-	/**
-	* Maintains the local collection of configuration property objects and their specified values
-	* @property config
-	* @private
-	* @type Object
-	*/
-	var config = {};
-
-	/**
-	* Maintains the local collection of configuration property objects as they were initially applied.
-	* This object is used when resetting a property.
-	* @property initialConfig
-	* @private
-	* @type Object
-	*/
-	var initialConfig = {};
-
-	/**
-	* Maintains the local, normalized CustomEvent queue
-	* @property eventQueue
-	* @private
-	* @type Object
-	*/
-	var eventQueue = [];
-
-	/**
-	* Fires a configuration property event using the specified value.
-	* @method fireEvent
-	* @private
-	* @param {String}	key			The configuration property's name
-	* @param {value}	Object		The value of the correct type for the property
-	*/
-	var fireEvent = function( key, value ) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-
-		if (typeof property != 'undefined' && property.event) {
-			property.event.fire(value);
-		}
-	};
-	/* End Private Members */
-
-	/**
-	* Adds a property to the Config Object's private config hash.
-	* @method addProperty
-	* @param {String}	key	The configuration property's name
-	* @param {Object}	propertyObject	The Object containing all of this property's arguments
-	*/
-	this.addProperty = function( key, propertyObject ) {
-		key = key.toLowerCase();
-
-		config[key] = propertyObject;
-
-		propertyObject.event = new YAHOO.util.CustomEvent(key);
-		propertyObject.key = key;
-
-		if (propertyObject.handler) {
-			propertyObject.event.subscribe(propertyObject.handler, this.owner, true);
-		}
-
-		this.setProperty(key, propertyObject.value, true);
-
-		if (! propertyObject.suppressEvent) {
-			this.queueProperty(key, propertyObject.value);
-		}
-	};
-
-	/**
-	* Returns a key-value configuration map of the values currently set in the Config Object.
-	* @method getConfig
-	* @return {Object} The current config, represented in a key-value map
-	*/
-	this.getConfig = function() {
-		var cfg = {};
-
-		for (var prop in config) {
-			var property = config[prop];
-			if (typeof property != 'undefined' && property.event) {
-				cfg[prop] = property.value;
-			}
-		}
-
-		return cfg;
-	};
-
-	/**
-	* Returns the value of specified property.
-	* @method getProperty
-	* @param {String} key	The name of the property
-	* @return {Object}		The value of the specified property
-	*/
-	this.getProperty = function(key) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			return property.value;
-		} else {
-			return undefined;
-		}
-	};
-
-	/**
-	* Resets the specified property's value to its initial value.
-	* @method resetProperty
-	* @param {String} key	The name of the property
-	* @return {Boolean} True is the property was reset, false if not
-	*/
-	this.resetProperty = function(key) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			if (initialConfig[key] && initialConfig[key] != 'undefined')	{
-				this.setProperty(key, initialConfig[key]);
-			}
-			return true;
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Sets the value of a property. If the silent property is passed as true, the property's event will not be fired.
-	* @method setProperty
-	* @param {String} key		The name of the property
-	* @param {String} value		The value to set the property to
-	* @param {Boolean} silent	Whether the value should be set silently, without firing the property event.
-	* @return {Boolean}			True, if the set was successful, false if it failed.
-	*/
-	this.setProperty = function(key, value, silent) {
-		key = key.toLowerCase();
-
-		if (this.queueInProgress && ! silent) {
-			this.queueProperty(key,value); // Currently running through a queue...
-			return true;
-		} else {
-			var property = config[key];
-			if (typeof property != 'undefined' && property.event) {
-				if (property.validator && ! property.validator(value)) { // validator
-					return false;
-				} else {
-					property.value = value;
-					if (! silent) {
-						fireEvent(key, value);
-						this.configChangedEvent.fire([key, value]);
-					}
-					return true;
-				}
-			} else {
-				return false;
-			}
-		}
-	};
-
-	/**
-	* Sets the value of a property and queues its event to execute. If the event is already scheduled to execute, it is
-	* moved from its current position to the end of the queue.
-	* @method queueProperty
-	* @param {String} key	The name of the property
-	* @param {String} value	The value to set the property to
-	* @return {Boolean}		true, if the set was successful, false if it failed.
-	*/
-	this.queueProperty = function(key, value) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-
-		if (typeof property != 'undefined' && property.event) {
-			if (typeof value != 'undefined' && property.validator && ! property.validator(value)) { // validator
-				return false;
-			} else {
-
-				if (typeof value != 'undefined') {
-					property.value = value;
-				} else {
-					value = property.value;
-				}
-
-				var foundDuplicate = false;
-
-				for (var i=0;i<eventQueue.length;i++) {
-					var queueItem = eventQueue[i];
-
-					if (queueItem) {
-						var queueItemKey = queueItem[0];
-						var queueItemValue = queueItem[1];
-
-						if (queueItemKey.toLowerCase() == key) {
-							// found a dupe... push to end of queue, null current item, and break
-							eventQueue[i] = null;
-							eventQueue.push([key, (typeof value != 'undefined' ? value : queueItemValue)]);
-							foundDuplicate = true;
-							break;
-						}
-					}
-				}
-
-				if (! foundDuplicate && typeof value != 'undefined') { // this is a refire, or a new property in the queue
-					eventQueue.push([key, value]);
-				}
-			}
-
-			if (property.supercedes) {
-				for (var s=0;s<property.supercedes.length;s++) {
-					var supercedesCheck = property.supercedes[s];
-
-					for (var q=0;q<eventQueue.length;q++) {
-						var queueItemCheck = eventQueue[q];
-
-						if (queueItemCheck) {
-							var queueItemCheckKey = queueItemCheck[0];
-							var queueItemCheckValue = queueItemCheck[1];
-
-							if ( queueItemCheckKey.toLowerCase() == supercedesCheck.toLowerCase() ) {
-								eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
-								eventQueue[q] = null;
-								break;
-							}
-						}
-					}
-				}
-			}
-
-			return true;
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Fires the event for a property using the property's current value.
-	* @method refireEvent
-	* @param {String} key	The name of the property
-	*/
-	this.refireEvent = function(key) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event && typeof property.value != 'undefined') {
-			if (this.queueInProgress) {
-				this.queueProperty(key);
-			} else {
-				fireEvent(key, property.value);
-			}
-		}
-	};
-
-	/**
-	* Applies a key-value Object literal to the configuration, replacing any existing values, and queueing the property events.
-	* Although the values will be set, fireQueue() must be called for their associated events to execute.
-	* @method applyConfig
-	* @param {Object}	userConfig	The configuration Object literal
-	* @param {Boolean}	init		When set to true, the initialConfig will be set to the userConfig passed in, so that calling a reset will reset the properties to the passed values.
-	*/
-	this.applyConfig = function(userConfig, init) {
-		if (init) {
-			initialConfig = userConfig;
-		}
-		for (var prop in userConfig) {
-			this.queueProperty(prop, userConfig[prop]);
-		}
-	};
-
-	/**
-	* Refires the events for all configuration properties using their current values.
-	* @method refresh
-	*/
-	this.refresh = function() {
-		for (var prop in config) {
-			this.refireEvent(prop);
-		}
-	};
-
-	/**
-	* Fires the normalized list of queued property change events
-	* @method fireQueue
-	*/
-	this.fireQueue = function() {
-		this.queueInProgress = true;
-		for (var i=0;i<eventQueue.length;i++) {
-			var queueItem = eventQueue[i];
-			if (queueItem) {
-				var key = queueItem[0];
-				var value = queueItem[1];
-
-				var property = config[key];
-				property.value = value;
-
-				fireEvent(key,value);
-			}
-		}
-
-		this.queueInProgress = false;
-		eventQueue = [];
-	};
-
-	/**
-	* Subscribes an external handler to the change event for any given property.
-	* @method subscribeToConfigEvent
-	* @param {String}	key			The property name
-	* @param {Function}	handler		The handler function to use subscribe to the property's event
-	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
-	* @param {Boolean}	override	Optional. If true, will override "this" within the handler to map to the scope Object passed into the method.
-	* @return {Boolean}				True, if the subscription was successful, otherwise false.
-	*/
-	this.subscribeToConfigEvent = function(key, handler, obj, override) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, obj)) {
-				property.event.subscribe(handler, obj, override);
-			}
-			return true;
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Unsubscribes an external handler from the change event for any given property.
-	* @method unsubscribeFromConfigEvent
-	* @param {String}	key			The property name
-	* @param {Function}	handler		The handler function to use subscribe to the property's event
-	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
-	* @return {Boolean}				True, if the unsubscription was successful, otherwise false.
-	*/
-	this.unsubscribeFromConfigEvent = function(key, handler, obj) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			return property.event.unsubscribe(handler, obj);
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Returns a string representation of the Config object
-	* @method toString
-	* @return {String}	The Config object in string format.
-	*/
-	this.toString = function() {
-		var output = "Config";
-		if (this.owner) {
-			output += " [" + this.owner.toString() + "]";
-		}
-		return output;
-	};
-
-	/**
-	* Returns a string representation of the Config object's current CustomEvent queue
-	* @method outputEventQueue
-	* @return {String}	The string list of CustomEvents currently queued for execution
-	*/
-	this.outputEventQueue = function() {
-		var output = "";
-		for (var q=0;q<eventQueue.length;q++) {
-			var queueItem = eventQueue[q];
-			if (queueItem) {
-				output += queueItem[0] + "=" + queueItem[1] + ", ";
-			}
-		}
-		return output;
-	};
-};
-
-/**
-* Checks to determine if a particular function/Object pair are already subscribed to the specified CustomEvent
-* @method YAHOO.util.Config.alreadySubscribed
-* @static
-* @param {YAHOO.util.CustomEvent} evt	The CustomEvent for which to check the subscriptions
-* @param {Function}	fn	The function to look for in the subscribers list
-* @param {Object}	obj	The execution scope Object for the subscription
-* @return {Boolean}	true, if the function/Object pair is already subscribed to the CustomEvent passed in
-*/
-YAHOO.util.Config.alreadySubscribed = function(evt, fn, obj) {
-	for (var e=0;e<evt.subscribers.length;e++) {
-		var subsc = evt.subscribers[e];
-		if (subsc && subsc.obj == obj && subsc.fn == fn) {
-			return true;
-		}
-	}
-	return false;
-};
-
-/**
-* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
-* used for adding, subtracting, and comparing dates.
-* @class YAHOO.widget.DateMath
-*/
-YAHOO.widget.DateMath = {
-	/**
-	* Constant field representing Day
-	* @property DAY
-	* @static
-	* @final
-	* @type String
-	*/
-	DAY : "D",
-
-	/**
-	* Constant field representing Week
-	* @property WEEK
-	* @static
-	* @final
-	* @type String
-	*/
-	WEEK : "W",
-
-	/**
-	* Constant field representing Year
-	* @property YEAR
-	* @static
-	* @final
-	* @type String
-	*/
-	YEAR : "Y",
-
-	/**
-	* Constant field representing Month
-	* @property MONTH
-	* @static
-	* @final
-	* @type String
-	*/
-	MONTH : "M",
-
-	/**
-	* Constant field representing one day, in milliseconds
-	* @property ONE_DAY_MS
-	* @static
-	* @final
-	* @type Number
-	*/
-	ONE_DAY_MS : 1000*60*60*24,
-
-	/**
-	* Adds the specified amount of time to the this instance.
-	* @method add
-	* @param {Date} date	The JavaScript Date object to perform addition on
-	* @param {String} field	The field constant to be used for performing addition.
-	* @param {Number} amount	The number of units (measured in the field constant) to add to the date.
-	* @return {Date} The resulting Date object
-	*/
-	add : function(date, field, amount) {
-		var d = new Date(date.getTime());
-		switch (field) {
-			case this.MONTH:
-				var newMonth = date.getMonth() + amount;
-				var years = 0;
-
-
-				if (newMonth < 0) {
-					while (newMonth < 0) {
-						newMonth += 12;
-						years -= 1;
-					}
-				} else if (newMonth > 11) {
-					while (newMonth > 11) {
-						newMonth -= 12;
-						years += 1;
-					}
-				}
-
-				d.setMonth(newMonth);
-				d.setFullYear(date.getFullYear() + years);
-				break;
-			case this.DAY:
-				d.setDate(date.getDate() + amount);
-				break;
-			case this.YEAR:
-				d.setFullYear(date.getFullYear() + amount);
-				break;
-			case this.WEEK:
-				d.setDate(date.getDate() + (amount * 7));
-				break;
-		}
-		return d;
-	},
-
-	/**
-	* Subtracts the specified amount of time from the this instance.
-	* @method subtract
-	* @param {Date} date	The JavaScript Date object to perform subtraction on
-	* @param {Number} field	The this field constant to be used for performing subtraction.
-	* @param {Number} amount	The number of units (measured in the field constant) to subtract from the date.
-	* @return {Date} The resulting Date object
-	*/
-	subtract : function(date, field, amount) {
-		return this.add(date, field, (amount*-1));
-	},
-
-	/**
-	* Determines whether a given date is before another date on the calendar.
-	* @method before
-	* @param {Date} date		The Date object to compare with the compare argument
-	* @param {Date} compareTo	The Date object to use for the comparison
-	* @return {Boolean} true if the date occurs before the compared date; false if not.
-	*/
-	before : function(date, compareTo) {
-		var ms = compareTo.getTime();
-		if (date.getTime() < ms) {
-			return true;
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	* Determines whether a given date is after another date on the calendar.
-	* @method after
-	* @param {Date} date		The Date object to compare with the compare argument
-	* @param {Date} compareTo	The Date object to use for the comparison
-	* @return {Boolean} true if the date occurs after the compared date; false if not.
-	*/
-	after : function(date, compareTo) {
-		var ms = compareTo.getTime();
-		if (date.getTime() > ms) {
-			return true;
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	* Determines whether a given date is between two other dates on the calendar.
-	* @method between
-	* @param {Date} date		The date to check for
-	* @param {Date} dateBegin	The start of the range
-	* @param {Date} dateEnd		The end of the range
-	* @return {Boolean} true if the date occurs between the compared dates; false if not.
-	*/
-	between : function(date, dateBegin, dateEnd) {
-		if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
-			return true;
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	* Retrieves a JavaScript Date object representing January 1 of any given year.
-	* @method getJan1
-	* @param {Number} calendarYear		The calendar year for which to retrieve January 1
-	* @return {Date}	January 1 of the calendar year specified.
-	*/
-	getJan1 : function(calendarYear) {
-		return new Date(calendarYear,0,1);
-	},
-
-	/**
-	* Calculates the number of days the specified date is from January 1 of the specified calendar year.
-	* Passing January 1 to this function would return an offset value of zero.
-	* @method getDayOffset
-	* @param {Date}	date	The JavaScript date for which to find the offset
-	* @param {Number} calendarYear	The calendar year to use for determining the offset
-	* @return {Number}	The number of days since January 1 of the given year
-	*/
-	getDayOffset : function(date, calendarYear) {
-		var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
-
-		// Find the number of days the passed in date is away from the calendar year start
-		var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
-		return dayOffset;
-	},
-
-	/**
-	* Calculates the week number for the given date. This function assumes that week 1 is the
-	* week in which January 1 appears, regardless of whether the week consists of a full 7 days.
-	* The calendar year can be specified to help find what a the week number would be for a given
-	* date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
-	* week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
-	* easily.
-	* @method getWeekNumber
-	* @param {Date}	date	The JavaScript date for which to find the week number
-	* @param {Number} calendarYear	OPTIONAL - The calendar year to use for determining the week number. Default is
-	*											the calendar year of parameter "date".
-	* @param {Number} weekStartsOn	OPTIONAL - The integer (0-6) representing which day a week begins on. Default is 0 (for Sunday).
-	* @return {Number}	The week number of the given date.
-	*/
-	getWeekNumber : function(date, calendarYear) {
-		date = this.clearTime(date);
-		var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
-
-		var jan1 = new Date(nearestThurs.getFullYear(),0,1);
-		var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
-
-		var weekNum = Math.ceil((dayOfYear)/ 7);
-		return weekNum;
-	},
-
-	/**
-	* Determines if a given week overlaps two different years.
-	* @method isYearOverlapWeek
-	* @param {Date}	weekBeginDate	The JavaScript Date representing the first day of the week.
-	* @return {Boolean}	true if the date overlaps two different years.
-	*/
-	isYearOverlapWeek : function(weekBeginDate) {
-		var overlaps = false;
-		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
-		if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
-			overlaps = true;
-		}
-		return overlaps;
-	},
-
-	/**
-	* Determines if a given week overlaps two different months.
-	* @method isMonthOverlapWeek
-	* @param {Date}	weekBeginDate	The JavaScript Date representing the first day of the week.
-	* @return {Boolean}	true if the date overlaps two different months.
-	*/
-	isMonthOverlapWeek : function(weekBeginDate) {
-		var overlaps = false;
-		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
-		if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
-			overlaps = true;
-		}
-		return overlaps;
-	},
-
-	/**
-	* Gets the first day of a month containing a given date.
-	* @method findMonthStart
-	* @param {Date}	date	The JavaScript Date used to calculate the month start
-	* @return {Date}		The JavaScript Date representing the first day of the month
-	*/
-	findMonthStart : function(date) {
-		var start = new Date(date.getFullYear(), date.getMonth(), 1);
-		return start;
-	},
-
-	/**
-	* Gets the last day of a month containing a given date.
-	* @method findMonthEnd
-	* @param {Date}	date	The JavaScript Date used to calculate the month end
-	* @return {Date}		The JavaScript Date representing the last day of the month
-	*/
-	findMonthEnd : function(date) {
-		var start = this.findMonthStart(date);
-		var nextMonth = this.add(start, this.MONTH, 1);
-		var end = this.subtract(nextMonth, this.DAY, 1);
-		return end;
-	},
-
-	/**
-	* Clears the time fields from a given date, effectively setting the time to midnight.
-	* @method clearTime
-	* @param {Date}	date	The JavaScript Date for which the time fields will be cleared
-	* @return {Date}		The JavaScript Date cleared of all time fields
-	*/
-	clearTime : function(date) {
-		date.setHours(12,0,0,0);
-		return date;
-	}
-};
-
-/**
-* The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month ("one-up") or two-month ("two-up") interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
-* @module    Calendar
-* @title     Calendar Widget
-* @namespace YAHOO.widget
-* @requires  yahoo,dom,event
-*/
-
-/**
-* Calendar is the base class for the Calendar widget. In its most basic
-* implementation, it has the ability to render a calendar widget on the page
-* that can be manipulated to select a single date, move back and forth between
-* months and years.
-* <p>To construct the placeholder for the calendar widget, the code is as
-* follows:
-*	<xmp>
-*		<div id="cal1Container"></div>
-*	</xmp>
-* Note that the table can be replaced with any kind of element.
-* </p>
-* @namespace YAHOO.widget
-* @class Calendar
-* @constructor
-* @param {String}	id			The id of the table element that will represent the calendar widget
-* @param {String}	containerId	The id of the container div element that will wrap the calendar table
-* @param {Object}	config		The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.Calendar = function(id, containerId, config) {
-	this.init(id, containerId, config);
-};
-
-/**
-* The path to be used for images loaded for the Calendar
-* @property YAHOO.widget.Calendar.IMG_ROOT
-* @static
-* @type String
-*/
-YAHOO.widget.Calendar.IMG_ROOT = (window.location.href.toLowerCase().indexOf("https") === 0 ? "https://a248.e.akamai.net/sec.yimg.com/i/" : "http://us.i1.yimg.com/us.yimg.com/i/");
-
-/**
-* Type constant used for renderers to represent an individual date (M/D/Y)
-* @property YAHOO.widget.Calendar.DATE
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Calendar.DATE = "D";
-
-/**
-* Type constant used for renderers to represent an individual date across any year (M/D)
-* @property YAHOO.widget.Calendar.MONTH_DAY
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Calendar.MONTH_DAY = "MD";
-
-/**
-* Type constant used for renderers to represent a weekday
-* @property YAHOO.widget.Calendar.WEEKDAY
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Calendar.WEEKDAY = "WD";
-
-/**
-* Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
-* @property YAHOO.widget.Calendar.RANGE
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Calendar.RANGE = "R";
-
-/**
-* Type constant used for renderers to represent a month across any year
-* @property YAHOO.widget.Calendar.MONTH
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Calendar.MONTH = "M";
-
-/**
-* Constant that represents the total number of date cells that are displayed in a given month
-* @property YAHOO.widget.Calendar.DISPLAY_DAYS
-* @static
-* @final
-* @type Number
-*/
-YAHOO.widget.Calendar.DISPLAY_DAYS = 42;
-
-/**
-* Constant used for halting the execution of the remainder of the render stack
-* @property YAHOO.widget.Calendar.STOP_RENDER
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Calendar.STOP_RENDER = "S";
-
-YAHOO.widget.Calendar.prototype = {
-
-	/**
-	* The configuration object used to set up the calendars various locale and style options.
-	* @property Config
-	* @private
-	* @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
-	* @type Object
-	*/
-	Config : null,
-
-	/**
-	* The parent CalendarGroup, only to be set explicitly by the parent group
-	* @property parent
-	* @type CalendarGroup
-	*/
-	parent : null,
-
-	/**
-	* The index of this item in the parent group
-	* @property index
-	* @type Number
-	*/
-	index : -1,
-
-	/**
-	* The collection of calendar table cells
-	* @property cells
-	* @type HTMLTableCellElement[]
-	*/
-	cells : null,
-
-	/**
-	* The collection of calendar cell dates that is parallel to the cells collection. The array contains dates field arrays in the format of [YYYY, M, D].
-	* @property cellDates
-	* @type Array[](Number[])
-	*/
-	cellDates : null,
-
-	/**
-	* The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page.
-	* @property id
-	* @type String
-	*/
-	id : null,
-
-	/**
-	* The DOM element reference that points to this calendar's container element. The calendar will be inserted into this element when the shell is rendered.
-	* @property oDomContainer
-	* @type HTMLElement
-	*/
-	oDomContainer : null,
-
-	/**
-	* A Date object representing today's date.
-	* @property today
-	* @type Date
-	*/
-	today : null,
-
-	/**
-	* The list of render functions, along with required parameters, used to render cells.
-	* @property renderStack
-	* @type Array[]
-	*/
-	renderStack : null,
-
-	/**
-	* A copy of the initial render functions created before rendering.
-	* @property _renderStack
-	* @private
-	* @type Array
-	*/
-	_renderStack : null,
-
-	/**
-	* A Date object representing the month/year that the calendar is initially set to
-	* @property _pageDate
-	* @private
-	* @type Date
-	*/
-	_pageDate : null,
-
-	/**
-	* The private list of initially selected dates.
-	* @property _selectedDates
-	* @private
-	* @type Array
-	*/
-	_selectedDates : null,
-
-	/**
-	* A map of DOM event handlers to attach to cells associated with specific CSS class names
-	* @property domEventMap
-	* @type Object
-	*/
-	domEventMap : null
-};
-
-
-
-/**
-* Initializes the Calendar widget.
-* @method init
-* @param {String}	id			The id of the table element that will represent the calendar widget
-* @param {String}	containerId	The id of the container div element that will wrap the calendar table
-* @param {Object}	config		The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
-	this.initEvents();
-	this.today = new Date();
-	YAHOO.widget.DateMath.clearTime(this.today);
-
-	this.id = id;
-	this.oDomContainer = document.getElementById(containerId);
-
-	/**
-	* The Config object used to hold the configuration variables for the Calendar
-	* @property cfg
-	* @type YAHOO.util.Config
-	*/
-	this.cfg = new YAHOO.util.Config(this);
-
-	/**
-	* The local object which contains the Calendar's options
-	* @property Options
-	* @type Object
-	*/
-	this.Options = {};
-
-	/**
-	* The local object which contains the Calendar's locale settings
-	* @property Locale
-	* @type Object
-	*/
-	this.Locale = {};
-
-	this.initStyles();
-
-	YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
-	YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
-
-	this.cellDates = [];
-	this.cells = [];
-	this.renderStack = [];
-	this._renderStack = [];
-
-	this.setupConfig();
-
-	if (config) {
-		this.cfg.applyConfig(config, true);
-	}
-
-	this.cfg.fireQueue();
-};
-
-/**
-* Renders the built-in IFRAME shim for the IE6 and below
-* @method configIframe
-*/
-YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
-	var useIframe = args[0];
-
-	if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
-		if (useIframe) {
-			var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");
-
-			if (this.browser == "ie" && (pos == "absolute" || pos == "relative")) {
-				if (! YAHOO.util.Dom.inDocument(this.iframe)) {
-					this.iframe = document.createElement("iframe");
-					this.iframe.src = "javascript:false;";
-					YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
-					this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
-				}
-			}
-		} else {
-			if (this.iframe) {
-				if (this.iframe.parentNode) {
-					this.iframe.parentNode.removeChild(this.iframe);
-				}
-				this.iframe = null;
-			}
-		}
-	}
-};
-
-/**
-* Default handler for the "title" property
-* @method configTitle
-*/
-YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
-	var title = args[0];
-	var close = this.cfg.getProperty("close");
-
-	var titleDiv;
-
-	if (title && title !== "") {
-		titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
-		titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
-		titleDiv.innerHTML = title;
-		this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
-		YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
-	} else {
-		titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
-
-		if (titleDiv) {
-			YAHOO.util.Event.purgeElement(titleDiv);
-			this.oDomContainer.removeChild(titleDiv);
-		}
-		if (! close) {
-			YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
-		}
-	}
-};
-
-/**
-* Default handler for the "close" property
-* @method configClose
-*/
-YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
-	var close = args[0];
-	var title = this.cfg.getProperty("title");
-
-	var linkClose;
-
-	if (close === true) {
-		linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
-		linkClose.href = "javascript:void(null);";
-		linkClose.className = "link-close";
-		YAHOO.util.Event.addListener(linkClose, "click", this.hide, this, true);
-		var imgClose = document.createElement("img");
-		imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + "us/my/bn/x_d.gif";
-		imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
-		linkClose.appendChild(imgClose);
-		this.oDomContainer.appendChild(linkClose);
-		YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
-	} else {
-		linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
-
-		if (linkClose) {
-			YAHOO.util.Event.purgeElement(linkClose);
-			this.oDomContainer.removeChild(linkClose);
-		}
-		if (! title || title === "") {
-			YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
-		}
-	}
-};
-
-/**
-* Initializes Calendar's built-in CustomEvents
-* @method initEvents
-*/
-YAHOO.widget.Calendar.prototype.initEvents = function() {
-
-	/**
-	* Fired before a selection is made
-	* @event beforeSelectEvent
-	*/
-	this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");
-
-	/**
-	* Fired when a selection is made
-	* @event selectEvent
-	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
-	*/
-	this.selectEvent = new YAHOO.util.CustomEvent("select");
-
-	/**
-	* Fired before a selection is made
-	* @event beforeDeselectEvent
-	*/
-	this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");
-
-	/**
-	* Fired when a selection is made
-	* @event deselectEvent
-	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
-	*/
-	this.deselectEvent = new YAHOO.util.CustomEvent("deselect");
-
-	/**
-	* Fired when the Calendar page is changed
-	* @event changePageEvent
-	*/
-	this.changePageEvent = new YAHOO.util.CustomEvent("changePage");
-
-	/**
-	* Fired before the Calendar is rendered
-	* @event beforeRenderEvent
-	*/
-	this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
-
-	/**
-	* Fired when the Calendar is rendered
-	* @event renderEvent
-	*/
-	this.renderEvent = new YAHOO.util.CustomEvent("render");
-
-	/**
-	* Fired when the Calendar is reset
-	* @event resetEvent
-	*/
-	this.resetEvent = new YAHOO.util.CustomEvent("reset");
-
-	/**
-	* Fired when the Calendar is cleared
-	* @event clearEvent
-	*/
-	this.clearEvent = new YAHOO.util.CustomEvent("clear");
-
-	this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
-	this.selectEvent.subscribe(this.onSelect, this, true);
-	this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
-	this.deselectEvent.subscribe(this.onDeselect, this, true);
-	this.changePageEvent.subscribe(this.onChangePage, this, true);
-	this.renderEvent.subscribe(this.onRender, this, true);
-	this.resetEvent.subscribe(this.onReset, this, true);
-	this.clearEvent.subscribe(this.onClear, this, true);
-};
-
-
-/**
-* The default event function that is attached to a date link within a calendar cell
-* when the calendar is rendered.
-* @method doSelectCell
-* @param {DOMEvent} e	The event
-* @param {Calendar} cal	A reference to the calendar passed by the Event utility
-*/
-YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
-	var target = YAHOO.util.Event.getTarget(e);
-
-	var cell,index,d,date;
-
-	while (target.tagName.toLowerCase() != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
-		target = target.parentNode;
-		if (target.tagName.toLowerCase() == "html") {
-			return;
-		}
-	}
-
-	cell = target;
-
-	if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
-		index = cell.id.split("cell")[1];
-		d = cal.cellDates[index];
-		date = new Date(d[0],d[1]-1,d[2]);
-
-		var link;
-
-		if (cal.Options.MULTI_SELECT) {
-			link = cell.getElementsByTagName("a")[0];
-			if (link) {
-				link.blur();
-			}
-
-			var cellDate = cal.cellDates[index];
-			var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
-
-			if (cellDateIndex > -1) {
-				cal.deselectCell(index);
-			} else {
-				cal.selectCell(index);
-			}
-
-		} else {
-			link = cell.getElementsByTagName("a")[0];
-			if (link) {
-				link.blur();
-			}
-			cal.selectCell(index);
-		}
-	}
-};
-
-/**
-* The event that is executed when the user hovers over a cell
-* @method doCellMouseOver
-* @param {DOMEvent} e	The event
-* @param {Calendar} cal	A reference to the calendar passed by the Event utility
-*/
-YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
-	var target;
-	if (e) {
-		target = YAHOO.util.Event.getTarget(e);
-	} else {
-		target = this;
-	}
-
-	while (target.tagName.toLowerCase() != "td") {
-		target = target.parentNode;
-		if (target.tagName.toLowerCase() == "html") {
-			return;
-		}
-	}
-
-	if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
-		YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
-	}
-};
-
-/**
-* The event that is executed when the user moves the mouse out of a cell
-* @method doCellMouseOut
-* @param {DOMEvent} e	The event
-* @param {Calendar} cal	A reference to the calendar passed by the Event utility
-*/
-YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
-	var target;
-	if (e) {
-		target = YAHOO.util.Event.getTarget(e);
-	} else {
-		target = this;
-	}
-
-	while (target.tagName.toLowerCase() != "td") {
-		target = target.parentNode;
-		if (target.tagName.toLowerCase() == "html") {
-			return;
-		}
-	}
-
-	if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
-		YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
-	}
-};
-
-YAHOO.widget.Calendar.prototype.setupConfig = function() {
-
-	/**
-	* The month/year representing the current visible Calendar date (mm/yyyy)
-	* @config pagedate
-	* @type String
-	* @default today's date
-	*/
-	this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );
-
-	/**
-	* The date or range of dates representing the current Calendar selection
-	* @config selected
-	* @type String
-	* @default []
-	*/
-	this.cfg.addProperty("selected", { value:[], handler:this.configSelected } );
-
-	/**
-	* The title to display above the Calendar's month header
-	* @config title
-	* @type String
-	* @default ""
-	*/
-	this.cfg.addProperty("title", { value:"", handler:this.configTitle } );
-
-	/**
-	* Whether or not a close button should be displayed for this Calendar
-	* @config close
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("close", { value:false, handler:this.configClose } );
-
-	/**
-	* Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
-	* @config iframe
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("iframe", { value:true, handler:this.configIframe, validator:this.cfg.checkBoolean } );
-
-	/**
-	* The minimum selectable date in the current Calendar (mm/dd/yyyy)
-	* @config mindate
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("mindate", { value:null, handler:this.configMinDate } );
-
-	/**
-	* The maximum selectable date in the current Calendar (mm/dd/yyyy)
-	* @config maxdate
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("maxdate", { value:null, handler:this.configMaxDate } );
-
-
-	// Options properties
-
-	/**
-	* True if the Calendar should allow multiple selections. False by default.
-	* @config MULTI_SELECT
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("MULTI_SELECT",	{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-
-    /**
-    * True if the Calendar should allow selection of out-of-month dates. False by default.
-    * @config OOM_SELECT
-    * @type Boolean
-    * @default false
-    */
-    this.cfg.addProperty("OOM_SELECT",      { value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-
-	/**
-	* The weekday the week begins on. Default is 0 (Sunday).
-	* @config START_WEEKDAY
-	* @type number
-	* @default 0
-	*/
-	this.cfg.addProperty("START_WEEKDAY",	{ value:0, handler:this.configOptions, validator:this.cfg.checkNumber  } );
-
-	/**
-	* True if the Calendar should show weekday labels. True by default.
-	* @config SHOW_WEEKDAYS
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("SHOW_WEEKDAYS",	{ value:true, handler:this.configOptions, validator:this.cfg.checkBoolean  } );
-
-	/**
-	* True if the Calendar should show week row headers. False by default.
-	* @config SHOW_WEEK_HEADER
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-
-	/**
-	* True if the Calendar should show week row footers. False by default.
-	* @config SHOW_WEEK_FOOTER
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-
-	/**
-	* True if the Calendar should suppress weeks that are not a part of the current month. False by default.
-	* @config HIDE_BLANK_WEEKS
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-
-	/**
-	* The image that should be used for the left navigation arrow.
-	* @config NAV_ARROW_LEFT
-	* @type String
-	* @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif"
-	*/
-	this.cfg.addProperty("NAV_ARROW_LEFT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.configOptions } );
-
-	/**
-	* The image that should be used for the left navigation arrow.
-	* @config NAV_ARROW_RIGHT
-	* @type String
-	* @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif"
-	*/
-	this.cfg.addProperty("NAV_ARROW_RIGHT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.configOptions } );
-
-	// Locale properties
-
-	/**
-	* The short month labels for the current locale.
-	* @config MONTHS_SHORT
-	* @type String[]
-	* @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
-	*/
-	this.cfg.addProperty("MONTHS_SHORT",	{ value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.configLocale } );
-
-	/**
-	* The long month labels for the current locale.
-	* @config MONTHS_LONG
-	* @type String[]
-	* @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
-	*/
-	this.cfg.addProperty("MONTHS_LONG",		{ value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.configLocale } );
-
-	/**
-	* The 1-character weekday labels for the current locale.
-	* @config WEEKDAYS_1CHAR
-	* @type String[]
-	* @default ["S", "M", "T", "W", "T", "F", "S"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_1CHAR",	{ value:["S", "M", "T", "W", "T", "F", "S"], handler:this.configLocale } );
-
-	/**
-	* The short weekday labels for the current locale.
-	* @config WEEKDAYS_SHORT
-	* @type String[]
-	* @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_SHORT",	{ value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.configLocale } );
-
-	/**
-	* The medium weekday labels for the current locale.
-	* @config WEEKDAYS_MEDIUM
-	* @type String[]
-	* @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_MEDIUM",	{ value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.configLocale } );
-
-	/**
-	* The long weekday labels for the current locale.
-	* @config WEEKDAYS_LONG
-	* @type String[]
-	* @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_LONG",	{ value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.configLocale } );
-
-	/**
-	* Refreshes the locale values used to build the Calendar.
-	* @method refreshLocale
-	* @private
-	*/
-	var refreshLocale = function() {
-		this.cfg.refireEvent("LOCALE_MONTHS");
-		this.cfg.refireEvent("LOCALE_WEEKDAYS");
-	};
-
-	this.cfg.subscribeToConfigEvent("START_WEEKDAY", refreshLocale, this, true);
-	this.cfg.subscribeToConfigEvent("MONTHS_SHORT", refreshLocale, this, true);
-	this.cfg.subscribeToConfigEvent("MONTHS_LONG", refreshLocale, this, true);
-	this.cfg.subscribeToConfigEvent("WEEKDAYS_1CHAR", refreshLocale, this, true);
-	this.cfg.subscribeToConfigEvent("WEEKDAYS_SHORT", refreshLocale, this, true);
-	this.cfg.subscribeToConfigEvent("WEEKDAYS_MEDIUM", refreshLocale, this, true);
-	this.cfg.subscribeToConfigEvent("WEEKDAYS_LONG", refreshLocale, this, true);
-
-	/**
-	* The setting that determines which length of month labels should be used. Possible values are "short" and "long".
-	* @config LOCALE_MONTHS
-	* @type String
-	* @default "long"
-	*/
-	this.cfg.addProperty("LOCALE_MONTHS",	{ value:"long", handler:this.configLocaleValues } );
-
-	/**
-	* The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
-	* @config LOCALE_WEEKDAYS
-	* @type String
-	* @default "short"
-	*/
-	this.cfg.addProperty("LOCALE_WEEKDAYS",	{ value:"short", handler:this.configLocaleValues } );
-
-	/**
-	* The value used to delimit individual dates in a date string passed to various Calendar functions.
-	* @config DATE_DELIMITER
-	* @type String
-	* @default ","
-	*/
-	this.cfg.addProperty("DATE_DELIMITER",		{ value:",", handler:this.configLocale } );
-
-	/**
-	* The value used to delimit date fields in a date string passed to various Calendar functions.
-	* @config DATE_FIELD_DELIMITER
-	* @type String
-	* @default "/"
-	*/
-	this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.configLocale } );
-
-	/**
-	* The value used to delimit date ranges in a date string passed to various Calendar functions.
-	* @config DATE_RANGE_DELIMITER
-	* @type String
-	* @default "-"
-	*/
-	this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.configLocale } );
-
-	/**
-	* The position of the month in a month/year date string
-	* @config MY_MONTH_POSITION
-	* @type Number
-	* @default 1
-	*/
-	this.cfg.addProperty("MY_MONTH_POSITION",	{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the year in a month/year date string
-	* @config MY_YEAR_POSITION
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("MY_YEAR_POSITION",	{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the month in a month/day date string
-	* @config MD_MONTH_POSITION
-	* @type Number
-	* @default 1
-	*/
-	this.cfg.addProperty("MD_MONTH_POSITION",	{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the day in a month/year date string
-	* @config MD_DAY_POSITION
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("MD_DAY_POSITION",		{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the month in a month/day/year date string
-	* @config MDY_MONTH_POSITION
-	* @type Number
-	* @default 1
-	*/
-	this.cfg.addProperty("MDY_MONTH_POSITION",	{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the day in a month/day/year date string
-	* @config MDY_DAY_POSITION
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("MDY_DAY_POSITION",	{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the year in a month/day/year date string
-	* @config MDY_YEAR_POSITION
-	* @type Number
-	* @default 3
-	*/
-	this.cfg.addProperty("MDY_YEAR_POSITION",	{ value:3, handler:this.configLocale, validator:this.cfg.checkNumber } );
-};
-
-/**
-* The default handler for the "pagedate" property
-* @method configPageDate
-*/
-YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
-	var val = args[0];
-	var month, year, aMonthYear;
-
-	if (val) {
-		if (val instanceof Date) {
-			val = YAHOO.widget.DateMath.findMonthStart(val);
-			this.cfg.setProperty("pagedate", val, true);
-			if (! this._pageDate) {
-				this._pageDate = this.cfg.getProperty("pagedate");
-			}
-			return;
-		} else {
-			aMonthYear = val.split(this.cfg.getProperty("DATE_FIELD_DELIMITER"));
-			month = parseInt(aMonthYear[this.cfg.getProperty("MY_MONTH_POSITION")-1], 10)-1;
-			year = parseInt(aMonthYear[this.cfg.getProperty("MY_YEAR_POSITION")-1], 10);
-		}
-	} else {
-		month = this.today.getMonth();
-		year = this.today.getFullYear();
-	}
-
-	this.cfg.setProperty("pagedate", new Date(year, month, 1), true);
-	if (! this._pageDate) {
-		this._pageDate = this.cfg.getProperty("pagedate");
-	}
-};
-
-/**
-* The default handler for the "mindate" property
-* @method configMinDate
-*/
-YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
-	var val = args[0];
-	if (typeof val == 'string') {
-		val = this._parseDate(val);
-		this.cfg.setProperty("mindate", new Date(val[0],(val[1]-1),val[2]));
-	}
-};
-
-/**
-* The default handler for the "maxdate" property
-* @method configMaxDate
-*/
-YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
-	var val = args[0];
-	if (typeof val == 'string') {
-		val = this._parseDate(val);
-		this.cfg.setProperty("maxdate", new Date(val[0],(val[1]-1),val[2]));
-	}
-};
-
-/**
-* The default handler for the "selected" property
-* @method configSelected
-*/
-YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
-	var selected = args[0];
-
-	if (selected) {
-		if (typeof selected == 'string') {
-			this.cfg.setProperty("selected", this._parseDates(selected), true);
-		}
-	}
-	if (! this._selectedDates) {
-		this._selectedDates = this.cfg.getProperty("selected");
-	}
-};
-
-/**
-* The default handler for all configuration options properties
-* @method configOptions
-*/
-YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
-	type = type.toUpperCase();
-	var val = args[0];
-	this.Options[type] = val;
-};
-
-/**
-* The default handler for all configuration locale properties
-* @method configLocale
-*/
-YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
-	type = type.toUpperCase();
-	var val = args[0];
-	this.Locale[type] = val;
-
-	this.cfg.refireEvent("LOCALE_MONTHS");
-	this.cfg.refireEvent("LOCALE_WEEKDAYS");
-
-};
-
-/**
-* The default handler for all configuration locale field length properties
-* @method configLocaleValues
-*/
-YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
-	type = type.toUpperCase();
-	var val = args[0];
-
-	switch (type) {
-		case "LOCALE_MONTHS":
-			switch (val) {
-				case "short":
-					this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_SHORT").concat();
-					break;
-				case "long":
-					this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_LONG").concat();
-					break;
-			}
-			break;
-		case "LOCALE_WEEKDAYS":
-			switch (val) {
-				case "1char":
-					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_1CHAR").concat();
-					break;
-				case "short":
-					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_SHORT").concat();
-					break;
-				case "medium":
-					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_MEDIUM").concat();
-					break;
-				case "long":
-					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_LONG").concat();
-					break;
-			}
-
-			var START_WEEKDAY = this.cfg.getProperty("START_WEEKDAY");
-
-			if (START_WEEKDAY > 0) {
-				for (var w=0;w<START_WEEKDAY;++w) {
-					this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());
-				}
-			}
-			break;
-	}
-};
-
-/**
-* Defines the style constants for the Calendar
-* @method initStyles
-*/
-YAHOO.widget.Calendar.prototype.initStyles = function() {
-
-	/**
-	* Collection of Style constants for the Calendar
-	* @property Style
-	*/
-	this.Style = {
-		/**
-		* @property Style.CSS_ROW_HEADER
-		*/
-		CSS_ROW_HEADER: "calrowhead",
-		/**
-		* @property Style.CSS_ROW_FOOTER
-		*/
-		CSS_ROW_FOOTER: "calrowfoot",
-		/**
-		* @property Style.CSS_CELL
-		*/
-		CSS_CELL : "calcell",
-		/**
-		* @property Style.CSS_CELL_SELECTED
-		*/
-		CSS_CELL_SELECTED : "selected",
-		/**
-		* @property Style.CSS_CELL_SELECTABLE
-		*/
-		CSS_CELL_SELECTABLE : "selectable",
-		/**
-		* @property Style.CSS_CELL_RESTRICTED
-		*/
-		CSS_CELL_RESTRICTED : "restricted",
-		/**
-		* @property Style.CSS_CELL_TODAY
-		*/
-		CSS_CELL_TODAY : "today",
-		/**
-		* @property Style.CSS_CELL_OOM
-		*/
-		CSS_CELL_OOM : "oom",
-		/**
-		* @property Style.CSS_CELL_OOB
-		*/
-		CSS_CELL_OOB : "previous",
-		/**
-		* @property Style.CSS_HEADER
-		*/
-		CSS_HEADER : "calheader",
-		/**
-		* @property Style.CSS_HEADER_TEXT
-		*/
-		CSS_HEADER_TEXT : "calhead",
-		/**
-		* @property Style.CSS_WEEKDAY_CELL
-		*/
-		CSS_WEEKDAY_CELL : "calweekdaycell",
-		/**
-		* @property Style.CSS_WEEKDAY_ROW
-		*/
-		CSS_WEEKDAY_ROW : "calweekdayrow",
-		/**
-		* @property Style.CSS_FOOTER
-		*/
-		CSS_FOOTER : "calfoot",
-		/**
-		* @property Style.CSS_CALENDAR
-		*/
-		CSS_CALENDAR : "yui-calendar",
-		/**
-		* @property Style.CSS_SINGLE
-		*/
-		CSS_SINGLE : "single",
-		/**
-		* @property Style.CSS_CONTAINER
-		*/
-		CSS_CONTAINER : "yui-calcontainer",
-		/**
-		* @property Style.CSS_NAV_LEFT
-		*/
-		CSS_NAV_LEFT : "calnavleft",
-		/**
-		* @property Style.CSS_NAV_RIGHT
-		*/
-		CSS_NAV_RIGHT : "calnavright",
-		/**
-		* @property Style.CSS_CELL_TOP
-		*/
-		CSS_CELL_TOP : "calcelltop",
-		/**
-		* @property Style.CSS_CELL_LEFT
-		*/
-		CSS_CELL_LEFT : "calcellleft",
-		/**
-		* @property Style.CSS_CELL_RIGHT
-		*/
-		CSS_CELL_RIGHT : "calcellright",
-		/**
-		* @property Style.CSS_CELL_BOTTOM
-		*/
-		CSS_CELL_BOTTOM : "calcellbottom",
-		/**
-		* @property Style.CSS_CELL_HOVER
-		*/
-		CSS_CELL_HOVER : "calcellhover",
-		/**
-		* @property Style.CSS_CELL_HIGHLIGHT1
-		*/
-		CSS_CELL_HIGHLIGHT1 : "highlight1",
-		/**
-		* @property Style.CSS_CELL_HIGHLIGHT2
-		*/
-		CSS_CELL_HIGHLIGHT2 : "highlight2",
-		/**
-		* @property Style.CSS_CELL_HIGHLIGHT3
-		*/
-		CSS_CELL_HIGHLIGHT3 : "highlight3",
-		/**
-		* @property Style.CSS_CELL_HIGHLIGHT4
-		*/
-		CSS_CELL_HIGHLIGHT4 : "highlight4"
-	};
-};
-
-/**
-* Builds the date label that will be displayed in the calendar header or
-* footer, depending on configuration.
-* @method buildMonthLabel
-* @return	{String}	The formatted calendar month label
-*/
-YAHOO.widget.Calendar.prototype.buildMonthLabel = function() {
-	var text = this.Locale.LOCALE_MONTHS[this.cfg.getProperty("pagedate").getMonth()] + " " + this.cfg.getProperty("pagedate").getFullYear();
-	return text;
-};
-
-/**
-* Builds the date digit that will be displayed in calendar cells
-* @method buildDayLabel
-* @param {Date}	workingDate	The current working date
-* @return	{String}	The formatted day label
-*/
-YAHOO.widget.Calendar.prototype.buildDayLabel = function(workingDate) {
-	var day = workingDate.getDate();
-	return day;
-};
-
-/**
-* Renders the calendar header.
-* @method renderHeader
-* @param {Array}	html	The current working HTML array
-* @return {Array} The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderHeader = function(html) {
-	var colSpan = 7;
-
-	if (this.cfg.getProperty("SHOW_WEEK_HEADER")) {
-		colSpan += 1;
-	}
-
-	if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) {
-		colSpan += 1;
-	}
-
-	html[html.length] = "<thead>";
-	html[html.length] =		"<tr>";
-	html[html.length] =			'<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
-	html[html.length] =				'<div class="' + this.Style.CSS_HEADER + '">';
-
-		var renderLeft, renderRight = false;
-
-		if (this.parent) {
-			if (this.index === 0) {
-				renderLeft = true;
-			}
-			if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
-				renderRight = true;
-			}
-		} else {
-			renderLeft = true;
-			renderRight = true;
-		}
-
-		var cal = this.parent || this;
-
-		if (renderLeft) {
-			html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '" style="background-image:url(' + this.cfg.getProperty("NAV_ARROW_LEFT") + ')">&#160;</a>';
-		}
-
-		html[html.length] = this.buildMonthLabel();
-
-		if (renderRight) {
-			html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '" style="background-image:url(' + this.cfg.getProperty("NAV_ARROW_RIGHT") + ')">&#160;</a>';
-		}
-
-
-	html[html.length] =				'</div>';
-	html[html.length] =			'</th>';
-	html[html.length] =		'</tr>';
-
-	if (this.cfg.getProperty("SHOW_WEEKDAYS")) {
-		html = this.buildWeekdays(html);
-	}
-
-	html[html.length] = '</thead>';
-
-	return html;
-};
-
-/**
-* Renders the Calendar's weekday headers.
-* @method buildWeekdays
-* @param {Array}	html	The current working HTML array
-* @return {Array} The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.buildWeekdays = function(html) {
-
-	html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';
-
-	if (this.cfg.getProperty("SHOW_WEEK_HEADER")) {
-		html[html.length] = '<th>&#160;</th>';
-	}
-
-	for(var i=0;i<this.Locale.LOCALE_WEEKDAYS.length;++i) {
-		html[html.length] = '<th class="calweekdaycell">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
-	}
-
-	if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) {
-		html[html.length] = '<th>&#160;</th>';
-	}
-
-	html[html.length] = '</tr>';
-
-	return html;
-};
-
-/**
-* Renders the calendar body.
-* @method renderBody
-* @param {Date}	workingDate	The current working Date being used for the render process
-* @param {Array}	html	The current working HTML array
-* @return {Array} The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderBody = function(workingDate, html) {
-
-	var startDay = this.cfg.getProperty("START_WEEKDAY");
-
-	this.preMonthDays = workingDate.getDay();
-	if (startDay > 0) {
-		this.preMonthDays -= startDay;
-	}
-	if (this.preMonthDays < 0) {
-		this.preMonthDays += 7;
-	}
-
-	this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
-	this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
-
-	workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
-
-	var useDate,weekNum,weekClass;
-	useDate = this.cfg.getProperty("pagedate");
-
-	html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + '">';
-
-	var i = 0;
-
-	var tempDiv = document.createElement("div");
-	var cell = document.createElement("td");
-	tempDiv.appendChild(cell);
-
-	var jan1 = new Date(useDate.getFullYear(),0,1);
-
-	var cal = this.parent || this;
-
-	for (var r=0;r<6;r++) {
-
-		weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);
-
-		weekClass = "w" + weekNum;
-
-		if (r !== 0 && (this.isDateOOM(workingDate) && !this.cfg.getProperty("OOM_SELECT")) && this.cfg.getProperty("HIDE_BLANK_WEEKS") === true) {
-			break;
-		} else {
-
-			html[html.length] = '<tr class="' + weekClass + '">';
-
-			if (this.cfg.getProperty("SHOW_WEEK_HEADER")) { html = this.renderRowHeader(weekNum, html); }
-
-			for (var d=0;d<7;d++){ // Render actual days
-
-				var cellRenderers = [];
-
-				this.clearElement(cell);
-
-				YAHOO.util.Dom.addClass(cell, "calcell");
-
-				cell.id = this.id + "_cell" + i;
-
-				cell.innerHTML = i;
-
-				var renderer = null;
-
-				if (workingDate.getFullYear()	== this.today.getFullYear() &&
-					workingDate.getMonth()		== this.today.getMonth() &&
-					workingDate.getDate()		== this.today.getDate()) {
-					cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
-				}
-
-				this.cellDates[this.cellDates.length]=[workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]; // Add this date to cellDates
-
-				if (this.isDateOOM(workingDate) && !this.cfg.getProperty("OOM_SELECT")) {
-					cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
-				} else {
-
-					YAHOO.util.Dom.addClass(cell, "wd" + workingDate.getDay());
-					YAHOO.util.Dom.addClass(cell, "d" + workingDate.getDate());
-
-					for (var s=0;s<this.renderStack.length;++s) {
-
-						var rArray = this.renderStack[s];
-						var type = rArray[0];
-
-						var month;
-						var day;
-						var year;
-
-						switch (type) {
-							case YAHOO.widget.Calendar.DATE:
-								month = rArray[1][1];
-								day = rArray[1][2];
-								year = rArray[1][0];
-
-								if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
-									renderer = rArray[2];
-									this.renderStack.splice(s,1);
-								}
-								break;
-							case YAHOO.widget.Calendar.MONTH_DAY:
-								month = rArray[1][0];
-								day = rArray[1][1];
-
-								if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
-									renderer = rArray[2];
-									this.renderStack.splice(s,1);
-								}
-								break;
-							case YAHOO.widget.Calendar.RANGE:
-								var date1 = rArray[1][0];
-								var date2 = rArray[1][1];
-
-								var d1month = date1[1];
-								var d1day = date1[2];
-								var d1year = date1[0];
-
-								var d1 = new Date(d1year, d1month-1, d1day);
-
-								var d2month = date2[1];
-								var d2day = date2[2];
-								var d2year = date2[0];
-
-								var d2 = new Date(d2year, d2month-1, d2day);
-
-								if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
-									renderer = rArray[2];
-
-									if (workingDate.getTime()==d2.getTime()) {
-										this.renderStack.splice(s,1);
-									}
-								}
-								break;
-							case YAHOO.widget.Calendar.WEEKDAY:
-
-								var weekday = rArray[1][0];
-								if (workingDate.getDay()+1 == weekday) {
-									renderer = rArray[2];
-								}
-								break;
-							case YAHOO.widget.Calendar.MONTH:
-
-								month = rArray[1][0];
-								if (workingDate.getMonth()+1 == month) {
-									renderer = rArray[2];
-								}
-								break;
-						}
-
-						if (renderer) {
-							cellRenderers[cellRenderers.length]=renderer;
-						}
-					}
-
-				}
-
-				if (this._indexOfSelectedFieldArray([workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]) > -1) {
-					cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
-				}
-
-				var mindate = this.cfg.getProperty("mindate");
-				var maxdate = this.cfg.getProperty("maxdate");
-
-				if (mindate) {
-					mindate = YAHOO.widget.DateMath.clearTime(mindate);
-				}
-				if (maxdate) {
-					maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
-				}
-
-				if (
-					(mindate && (workingDate.getTime() < mindate.getTime())) ||
-					(maxdate && (workingDate.getTime() > maxdate.getTime()))
-				) {
-					cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
-				} else {
-					cellRenderers[cellRenderers.length]=cal.styleCellDefault;
-					cellRenderers[cellRenderers.length]=cal.renderCellDefault;
-				}
-
-
-
-				for (var x=0;x<cellRenderers.length;++x) {
-					var ren = cellRenderers[x];
-					if (ren.call((this.parent || this),workingDate,cell) == YAHOO.widget.Calendar.STOP_RENDER) {
-						break;
-					}
-				}
-
-				workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
-
-				if (i >= 0 && i <= 6) {
-					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
-				}
-				if ((i % 7) === 0) {
-					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
-				}
-				if (((i+1) % 7) === 0) {
-					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
-				}
-
-				var postDays = this.postMonthDays;
-				if (postDays >= 7 && this.cfg.getProperty("HIDE_BLANK_WEEKS")) {
-					var blankWeeks = Math.floor(postDays/7);
-					for (var p=0;p<blankWeeks;++p) {
-						postDays -= 7;
-					}
-				}
-
-				if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
-					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
-				}
-
-				html[html.length] = tempDiv.innerHTML;
-
-				i++;
-			}
-
-			if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) { html = this.renderRowFooter(weekNum, html); }
-
-			html[html.length] = '</tr>';
-		}
-	}
-
-	html[html.length] = '</tbody>';
-
-	return html;
-};
-
-/**
-* Renders the calendar footer. In the default implementation, there is
-* no footer.
-* @method renderFooter
-* @param {Array}	html	The current working HTML array
-* @return {Array} The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderFooter = function(html) { return html; };
-
-/**
-* Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
-* when the method is called: renderHeader, renderBody, renderFooter.
-* Refer to the documentation for those methods for information on
-* individual render tasks.
-* @method render
-*/
-YAHOO.widget.Calendar.prototype.render = function() {
-	this.beforeRenderEvent.fire();
-
-	// Find starting day of the current month
-	var workingDate = YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty("pagedate"));
-
-	this.resetRenderers();
-	this.cellDates.length = 0;
-
-	YAHOO.util.Event.purgeElement(this.oDomContainer, true);
-
-	var html = [];
-
-	html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + workingDate.getFullYear() + '" id="' + this.id + '">';
-	html = this.renderHeader(html);
-	html = this.renderBody(workingDate, html);
-	html = this.renderFooter(html);
-	html[html.length] = '</table>';
-
-	this.oDomContainer.innerHTML = html.join("\n");
-
-	this.applyListeners();
-	this.cells = this.oDomContainer.getElementsByTagName("td");
-
-	this.cfg.refireEvent("title");
-	this.cfg.refireEvent("close");
-	this.cfg.refireEvent("iframe");
-
-	this.renderEvent.fire();
-};
-
-/**
-* Applies the Calendar's DOM listeners to applicable elements.
-* @method applyListeners
-*/
-YAHOO.widget.Calendar.prototype.applyListeners = function() {
-
-	var root = this.oDomContainer;
-	var cal = this.parent || this;
-
-	var linkLeft, linkRight;
-
-	linkLeft = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, "a", root);
-	linkRight = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, "a", root);
-
-	if (linkLeft) {
-		this.linkLeft = linkLeft[0];
-		YAHOO.util.Event.addListener(this.linkLeft, "mousedown", cal.previousMonth, cal, true);
-	}
-
-	if (linkRight) {
-		this.linkRight = linkRight[0];
-		YAHOO.util.Event.addListener(this.linkRight, "mousedown", cal.nextMonth, cal, true);
-	}
-
-	if (this.domEventMap) {
-		var el,elements;
-		for (var cls in this.domEventMap) {
-			if (this.domEventMap.hasOwnProperty(cls)) {
-				var items = this.domEventMap[cls];
-
-				if (! (items instanceof Array)) {
-					items = [items];
-				}
-
-				for (var i=0;i<items.length;i++)	{
-					var item = items[i];
-					elements = YAHOO.util.Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);
-
-					for (var c=0;c<elements.length;c++) {
-						el = elements[c];
-						 YAHOO.util.Event.addListener(el, item.event, item.handler, item.scope, item.correct );
-					}
-				}
-			}
-		}
-	}
-
-	YAHOO.util.Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
-	YAHOO.util.Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
-	YAHOO.util.Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
-};
-
-/**
-* Retrieves the Date object for the specified Calendar cell
-* @method getDateByCellId
-* @param {String}	id	The id of the cell
-* @return {Date} The Date object for the specified Calendar cell
-*/
-YAHOO.widget.Calendar.prototype.getDateByCellId = function(id) {
-	var date = this.getDateFieldsByCellId(id);
-	return new Date(date[0],date[1]-1,date[2]);
-};
-
-/**
-* Retrieves the Date object for the specified Calendar cell
-* @method getDateFieldsByCellId
-* @param {String}	id	The id of the cell
-* @return {Array}	The array of Date fields for the specified Calendar cell
-*/
-YAHOO.widget.Calendar.prototype.getDateFieldsByCellId = function(id) {
-	id = id.toLowerCase().split("_cell")[1];
-	id = parseInt(id, 10);
-	return this.cellDates[id];
-};
-
-// BEGIN BUILT-IN TABLE CELL RENDERERS
-
-/**
-* Renders a cell that falls before the minimum date or after the maximum date.
-* widget class.
-* @method renderOutOfBoundsDate
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
-*			should not be terminated
-*/
-YAHOO.widget.Calendar.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
-	cell.innerHTML = workingDate.getDate();
-	return YAHOO.widget.Calendar.STOP_RENDER;
-};
-
-/**
-* Renders the row header for a week.
-* @method renderRowHeader
-* @param {Number}	weekNum	The week number of the current row
-* @param {Array}	cell	The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderRowHeader = function(weekNum, html) {
-	html[html.length] = '<th class="calrowhead">' + weekNum + '</th>';
-	return html;
-};
-
-/**
-* Renders the row footer for a week.
-* @method renderRowFooter
-* @param {Number}	weekNum	The week number of the current row
-* @param {Array}	cell	The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderRowFooter = function(weekNum, html) {
-	html[html.length] = '<th class="calrowfoot">' + weekNum + '</th>';
-	return html;
-};
-
-/**
-* Renders a single standard calendar cell in the calendar widget table.
-* All logic for determining how a standard default cell will be rendered is
-* encapsulated in this method, and must be accounted for when extending the
-* widget class.
-* @method renderCellDefault
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell) {
-	cell.innerHTML = '<a href="javascript:void(null);" >' + this.buildDayLabel(workingDate) + "</a>";
-};
-
-/**
-* Styles a selectable cell.
-* @method styleCellDefault
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.styleCellDefault = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
-};
-
-
-/**
-* Renders a single standard calendar cell using the CSS hightlight1 style
-* @method renderCellStyleHighlight1
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
-};
-
-/**
-* Renders a single standard calendar cell using the CSS hightlight2 style
-* @method renderCellStyleHighlight2
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
-};
-
-/**
-* Renders a single standard calendar cell using the CSS hightlight3 style
-* @method renderCellStyleHighlight3
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
-};
-
-/**
-* Renders a single standard calendar cell using the CSS hightlight4 style
-* @method renderCellStyleHighlight4
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
-};
-
-/**
-* Applies the default style used for rendering today's date to the current calendar cell
-* @method renderCellStyleToday
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleToday = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
-};
-
-/**
-* Applies the default style used for rendering selected dates to the current calendar cell
-* @method renderCellStyleSelected
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
-*			should not be terminated
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleSelected = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
-};
-
-/**
-* Applies the default style used for rendering dates that are not a part of the current
-* month (preceding or trailing the cells for the current month)
-* @method renderCellNotThisMonth
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
-*			should not be terminated
-*/
-YAHOO.widget.Calendar.prototype.renderCellNotThisMonth = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);
-	cell.innerHTML=workingDate.getDate();
-	return YAHOO.widget.Calendar.STOP_RENDER;
-};
-
-/**
-* Renders the current calendar cell as a non-selectable "black-out" date using the default
-* restricted style.
-* @method renderBodyCellRestricted
-* @param {Date}					workingDate		The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
-* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
-*			should not be terminated
-*/
-YAHOO.widget.Calendar.prototype.renderBodyCellRestricted = function(workingDate, cell) {
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);
-	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
-	cell.innerHTML=workingDate.getDate();
-	return YAHOO.widget.Calendar.STOP_RENDER;
-};
-
-// END BUILT-IN TABLE CELL RENDERERS
-
-// BEGIN MONTH NAVIGATION METHODS
-
-/**
-* Adds the designated number of months to the current calendar month, and sets the current
-* calendar page date to the new month.
-* @method addMonths
-* @param {Number}	count	The number of months to add to the current calendar
-*/
-YAHOO.widget.Calendar.prototype.addMonths = function(count) {
-	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.add(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.MONTH, count));
-	this.resetRenderers();
-	this.changePageEvent.fire();
-};
-
-/**
-* Subtracts the designated number of months from the current calendar month, and sets the current
-* calendar page date to the new month.
-* @method subtractMonths
-* @param {Number}	count	The number of months to subtract from the current calendar
-*/
-YAHOO.widget.Calendar.prototype.subtractMonths = function(count) {
-	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.subtract(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.MONTH, count));
-	this.resetRenderers();
-	this.changePageEvent.fire();
-};
-
-/**
-* Adds the designated number of years to the current calendar, and sets the current
-* calendar page date to the new month.
-* @method addYears
-* @param {Number}	count	The number of years to add to the current calendar
-*/
-YAHOO.widget.Calendar.prototype.addYears = function(count) {
-	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.add(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.YEAR, count));
-	this.resetRenderers();
-	this.changePageEvent.fire();
-};
-
-/**
-* Subtcats the designated number of years from the current calendar, and sets the current
-* calendar page date to the new month.
-* @method subtractYears
-* @param {Number}	count	The number of years to subtract from the current calendar
-*/
-YAHOO.widget.Calendar.prototype.subtractYears = function(count) {
-	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.subtract(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.YEAR, count));
-	this.resetRenderers();
-	this.changePageEvent.fire();
-};
-
-/**
-* Navigates to the next month page in the calendar widget.
-* @method nextMonth
-*/
-YAHOO.widget.Calendar.prototype.nextMonth = function() {
-	this.addMonths(1);
-};
-
-/**
-* Navigates to the previous month page in the calendar widget.
-* @method previousMonth
-*/
-YAHOO.widget.Calendar.prototype.previousMonth = function() {
-	this.subtractMonths(1);
-};
-
-/**
-* Navigates to the next year in the currently selected month in the calendar widget.
-* @method nextYear
-*/
-YAHOO.widget.Calendar.prototype.nextYear = function() {
-	this.addYears(1);
-};
-
-/**
-* Navigates to the previous year in the currently selected month in the calendar widget.
-* @method previousYear
-*/
-YAHOO.widget.Calendar.prototype.previousYear = function() {
-	this.subtractYears(1);
-};
-
-// END MONTH NAVIGATION METHODS
-
-// BEGIN SELECTION METHODS
-
-/**
-* Resets the calendar widget to the originally selected month and year, and
-* sets the calendar to the initial selection(s).
-* @method reset
-*/
-YAHOO.widget.Calendar.prototype.reset = function() {
-	this.cfg.resetProperty("selected");
-	this.cfg.resetProperty("pagedate");
-	this.resetEvent.fire();
-};
-
-/**
-* Clears the selected dates in the current calendar widget and sets the calendar
-* to the current month and year.
-* @method clear
-*/
-YAHOO.widget.Calendar.prototype.clear = function() {
-	this.cfg.setProperty("selected", []);
-	this.cfg.setProperty("pagedate", new Date(this.today.getTime()));
-	this.clearEvent.fire();
-};
-
-/**
-* Selects a date or a collection of dates on the current calendar. This method, by default,
-* does not call the render method explicitly. Once selection has completed, render must be
-* called for the changes to be reflected visually.
-* @method select
-* @param	{String/Date/Date[]}	date	The date string of dates to select in the current calendar. Valid formats are
-*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
-*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
-*								This method can also take a JavaScript Date object or an array of Date objects.
-* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.select = function(date) {
-	this.beforeSelectEvent.fire();
-
-	var selected = this.cfg.getProperty("selected");
-	var aToBeSelected = this._toFieldArray(date);
-
-	for (var a=0;a<aToBeSelected.length;++a) {
-		var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
-		if (this._indexOfSelectedFieldArray(toSelect) == -1) { // not already selected?
-			selected[selected.length]=toSelect;
-		}
-	}
-
-	if (this.parent) {
-		this.parent.cfg.setProperty("selected", selected);
-	} else {
-		this.cfg.setProperty("selected", selected);
-	}
-
-	this.selectEvent.fire(aToBeSelected);
-
-	return this.getSelectedDates();
-};
-
-/**
-* Selects a date on the current calendar by referencing the index of the cell that should be selected.
-* This method is used to easily select a single cell (usually with a mouse click) without having to do
-* a full render. The selected style is applied to the cell directly.
-* @method selectCell
-* @param	{Number}	cellIndex	The index of the cell to select in the current calendar.
-* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.selectCell = function(cellIndex) {
-	this.beforeSelectEvent.fire();
-
-	var selected = this.cfg.getProperty("selected");
-
-	var cell = this.cells[cellIndex];
-	var cellDate = this.cellDates[cellIndex];
-
-	var dCellDate = this._toDate(cellDate);
-
-	var selectDate = cellDate.concat();
-
-	selected[selected.length] = selectDate;
-
-	if (this.parent) {
-		this.parent.cfg.setProperty("selected", selected);
-	} else {
-		this.cfg.setProperty("selected", selected);
-	}
-
-	this.renderCellStyleSelected(dCellDate,cell);
-
-	this.selectEvent.fire([selectDate]);
-
-	this.doCellMouseOut.call(cell, null, this);
-
-	return this.getSelectedDates();
-};
-
-/**
-* Deselects a date or a collection of dates on the current calendar. This method, by default,
-* does not call the render method explicitly. Once deselection has completed, render must be
-* called for the changes to be reflected visually.
-* @method deselect
-* @param	{String/Date/Date[]}	date	The date string of dates to deselect in the current calendar. Valid formats are
-*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
-*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
-*								This method can also take a JavaScript Date object or an array of Date objects.
-* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.deselect = function(date) {
-	this.beforeDeselectEvent.fire();
-
-	var selected = this.cfg.getProperty("selected");
-
-	var aToBeSelected = this._toFieldArray(date);
-
-	for (var a=0;a<aToBeSelected.length;++a) {
-		var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
-		var index = this._indexOfSelectedFieldArray(toSelect);
-
-		if (index != -1) {
-			selected.splice(index,1);
-		}
-	}
-
-	if (this.parent) {
-		this.parent.cfg.setProperty("selected", selected);
-	} else {
-		this.cfg.setProperty("selected", selected);
-	}
-
-	this.deselectEvent.fire(aToBeSelected);
-
-	return this.getSelectedDates();
-};
-
-/**
-* Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
-* This method is used to easily deselect a single cell (usually with a mouse click) without having to do
-* a full render. The selected style is removed from the cell directly.
-* @method deselectCell
-* @param	{Number}	cellIndex	The index of the cell to deselect in the current calendar.
-* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.deselectCell = function(i) {
-	this.beforeDeselectEvent.fire();
-
-	var selected = this.cfg.getProperty("selected");
-
-	var cell = this.cells[i];
-	var cellDate = this.cellDates[i];
-	var cellDateIndex = this._indexOfSelectedFieldArray(cellDate);
-
-	var dCellDate = this._toDate(cellDate);
-
-	var selectDate = cellDate.concat();
-
-	if (cellDateIndex > -1) {
-		if (this.cfg.getProperty("pagedate").getMonth() == dCellDate.getMonth() &&
-			this.cfg.getProperty("pagedate").getFullYear() == dCellDate.getFullYear()) {
-			YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
-		}
-
-		selected.splice(cellDateIndex, 1);
-	}
-
-
-	if (this.parent) {
-		this.parent.cfg.setProperty("selected", selected);
-	} else {
-		this.cfg.setProperty("selected", selected);
-	}
-
-	this.deselectEvent.fire(selectDate);
-	return this.getSelectedDates();
-};
-
-/**
-* Deselects all dates on the current calendar.
-* @method deselectAll
-* @return {Date[]}		Array of JavaScript Date objects representing all individual dates that are currently selected.
-*						Assuming that this function executes properly, the return value should be an empty array.
-*						However, the empty array is returned for the sake of being able to check the selection status
-*						of the calendar.
-*/
-YAHOO.widget.Calendar.prototype.deselectAll = function() {
-	this.beforeDeselectEvent.fire();
-
-	var selected = this.cfg.getProperty("selected");
-	var count = selected.length;
-	var sel = selected.concat();
-
-	if (this.parent) {
-		this.parent.cfg.setProperty("selected", []);
-	} else {
-		this.cfg.setProperty("selected", []);
-	}
-
-	if (count > 0) {
-		this.deselectEvent.fire(sel);
-	}
-
-	return this.getSelectedDates();
-};
-
-// END SELECTION METHODS
-
-// BEGIN TYPE CONVERSION METHODS
-
-/**
-* Converts a date (either a JavaScript Date object, or a date string) to the internal data structure
-* used to represent dates: [[yyyy,mm,dd],[yyyy,mm,dd]].
-* @method _toFieldArray
-* @private
-* @param	{String/Date/Date[]}	date	The date string of dates to deselect in the current calendar. Valid formats are
-*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
-*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
-*								This method can also take a JavaScript Date object or an array of Date objects.
-* @return {Array[](Number[])}	Array of date field arrays
-*/
-YAHOO.widget.Calendar.prototype._toFieldArray = function(date) {
-	var returnDate = [];
-
-	if (date instanceof Date) {
-		returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
-	} else if (typeof date == 'string') {
-		returnDate = this._parseDates(date);
-	} else if (date instanceof Array) {
-		for (var i=0;i<date.length;++i) {
-			var d = date[i];
-			returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
-		}
-	}
-
-	return returnDate;
-};
-
-/**
-* Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
-* @method _toDate
-* @private
-* @param	{Number[]}		dateFieldArray	The date field array to convert to a JavaScript Date.
-* @return	{Date}	JavaScript Date object representing the date field array
-*/
-YAHOO.widget.Calendar.prototype._toDate = function(dateFieldArray) {
-	if (dateFieldArray instanceof Date) {
-		return dateFieldArray;
-	} else {
-		return new Date(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
-	}
-};
-
-// END TYPE CONVERSION METHODS
-
-// BEGIN UTILITY METHODS
-
-/**
-* Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
-* @method _fieldArraysAreEqual
-* @private
-* @param	{Number[]}	array1	The first date field array to compare
-* @param	{Number[]}	array2	The first date field array to compare
-* @return	{Boolean}	The boolean that represents the equality of the two arrays
-*/
-YAHOO.widget.Calendar.prototype._fieldArraysAreEqual = function(array1, array2) {
-	var match = false;
-
-	if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
-		match=true;
-	}
-
-	return match;
-};
-
-/**
-* Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
-* @method	_indexOfSelectedFieldArray
-* @private
-* @param	{Number[]}		find	The date field array to search for
-* @return	{Number}			The index of the date field array within the collection of selected dates.
-*								-1 will be returned if the date is not found.
-*/
-YAHOO.widget.Calendar.prototype._indexOfSelectedFieldArray = function(find) {
-	var selected = -1;
-	var seldates = this.cfg.getProperty("selected");
-
-	for (var s=0;s<seldates.length;++s) {
-		var sArray = seldates[s];
-		if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
-			selected = s;
-			break;
-		}
-	}
-
-	return selected;
-};
-
-/**
-* Determines whether a given date is OOM (out of month).
-* @method	isDateOOM
-* @param	{Date}	date	The JavaScript Date object for which to check the OOM status
-* @return	{Boolean}	true if the date is OOM
-*/
-YAHOO.widget.Calendar.prototype.isDateOOM = function(date) {
-	var isOOM = false;
-	if (date.getMonth() != this.cfg.getProperty("pagedate").getMonth()) {
-		isOOM = true;
-	}
-	return isOOM;
-};
-
-// END UTILITY METHODS
-
-// BEGIN EVENT HANDLERS
-
-/**
-* Event executed before a date is selected in the calendar widget.
-* @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onBeforeSelect = function() {
-	if (this.cfg.getProperty("MULTI_SELECT") === false) {
-		if (this.parent) {
-			this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
-			this.parent.deselectAll();
-		} else {
-			this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
-			this.deselectAll();
-		}
-	}
-};
-
-/**
-* Event executed when a date is selected in the calendar widget.
-* @param	{Array}	selected	An array of date field arrays representing which date or dates were selected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
-* @deprecated Event handlers for this event should be susbcribed to selectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onSelect = function(selected) { };
-
-/**
-* Event executed before a date is deselected in the calendar widget.
-* @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onBeforeDeselect = function() { };
-
-/**
-* Event executed when a date is deselected in the calendar widget.
-* @param	{Array}	selected	An array of date field arrays representing which date or dates were deselected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
-* @deprecated Event handlers for this event should be susbcribed to deselectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onDeselect = function(deselected) { };
-
-/**
-* Event executed when the user navigates to a different calendar page.
-* @deprecated Event handlers for this event should be susbcribed to changePageEvent.
-*/
-YAHOO.widget.Calendar.prototype.onChangePage = function() {
-	this.render();
-};
-
-/**
-* Event executed when the calendar widget is rendered.
-* @deprecated Event handlers for this event should be susbcribed to renderEvent.
-*/
-YAHOO.widget.Calendar.prototype.onRender = function() { };
-
-/**
-* Event executed when the calendar widget is reset to its original state.
-* @deprecated Event handlers for this event should be susbcribed to resetEvemt.
-*/
-YAHOO.widget.Calendar.prototype.onReset = function() { this.render(); };
-
-/**
-* Event executed when the calendar widget is completely cleared to the current month with no selections.
-* @deprecated Event handlers for this event should be susbcribed to clearEvent.
-*/
-YAHOO.widget.Calendar.prototype.onClear = function() { this.render(); };
-
-/**
-* Validates the calendar widget. This method has no default implementation
-* and must be extended by subclassing the widget.
-* @return	Should return true if the widget validates, and false if
-* it doesn't.
-* @type Boolean
-*/
-YAHOO.widget.Calendar.prototype.validate = function() { return true; };
-
-// END EVENT HANDLERS
-
-// BEGIN DATE PARSE METHODS
-
-/**
-* Converts a date string to a date field array
-* @private
-* @param	{String}	sDate			Date string. Valid formats are mm/dd and mm/dd/yyyy.
-* @return				A date field array representing the string passed to the method
-* @type Array[](Number[])
-*/
-YAHOO.widget.Calendar.prototype._parseDate = function(sDate) {
-	var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER);
-	var rArray;
-
-	if (aDate.length == 2) {
-		rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
-		rArray.type = YAHOO.widget.Calendar.MONTH_DAY;
-	} else {
-		rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
-		rArray.type = YAHOO.widget.Calendar.DATE;
-	}
-
-	for (var i=0;i<rArray.length;i++) {
-		rArray[i] = parseInt(rArray[i], 10);
-	}
-
-	return rArray;
-};
-
-/**
-* Converts a multi or single-date string to an array of date field arrays
-* @private
-* @param	{String}	sDates		Date string with one or more comma-delimited dates. Valid formats are mm/dd, mm/dd/yyyy, mm/dd/yyyy-mm/dd/yyyy
-* @return							An array of date field arrays
-* @type Array[](Number[])
-*/
-YAHOO.widget.Calendar.prototype._parseDates = function(sDates) {
-	var aReturn = [];
-
-	var aDates = sDates.split(this.Locale.DATE_DELIMITER);
-
-	for (var d=0;d<aDates.length;++d) {
-		var sDate = aDates[d];
-
-		if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
-			// This is a range
-			var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER);
-
-			var dateStart = this._parseDate(aRange[0]);
-			var dateEnd = this._parseDate(aRange[1]);
-
-			var fullRange = this._parseRange(dateStart, dateEnd);
-			aReturn = aReturn.concat(fullRange);
-		} else {
-			// This is not a range
-			var aDate = this._parseDate(sDate);
-			aReturn.push(aDate);
-		}
-	}
-	return aReturn;
-};
-
-/**
-* Converts a date range to the full list of included dates
-* @private
-* @param	{Number[]}	startDate	Date field array representing the first date in the range
-* @param	{Number[]}	endDate		Date field array representing the last date in the range
-* @return							An array of date field arrays
-* @type Array[](Number[])
-*/
-YAHOO.widget.Calendar.prototype._parseRange = function(startDate, endDate) {
-	var dStart   = new Date(startDate[0],startDate[1]-1,startDate[2]);
-	var dCurrent = YAHOO.widget.DateMath.add(new Date(startDate[0],startDate[1]-1,startDate[2]),YAHOO.widget.DateMath.DAY,1);
-	var dEnd     = new Date(endDate[0],  endDate[1]-1,  endDate[2]);
-
-	var results = [];
-	results.push(startDate);
-	while (dCurrent.getTime() <= dEnd.getTime()) {
-		results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
-		dCurrent = YAHOO.widget.DateMath.add(dCurrent,YAHOO.widget.DateMath.DAY,1);
-	}
-	return results;
-};
-
-// END DATE PARSE METHODS
-
-// BEGIN RENDERER METHODS
-
-/**
-* Resets the render stack of the current calendar to its original pre-render value.
-*/
-YAHOO.widget.Calendar.prototype.resetRenderers = function() {
-	this.renderStack = this._renderStack.concat();
-};
-
-/**
-* Clears the inner HTML, CSS class and style information from the specified cell.
-* @method clearElement
-* @param	{HTMLTableCellElement}	The cell to clear
-*/
-YAHOO.widget.Calendar.prototype.clearElement = function(cell) {
-	cell.innerHTML = "&#160;";
-	cell.className="";
-};
-
-/**
-* Adds a renderer to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the conditions specified in the date string for this renderer.
-* @method addRenderer
-* @param	{String}	sDates		A date string to associate with the specified renderer. Valid formats
-*									include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.Calendar.prototype.addRenderer = function(sDates, fnRender) {
-	var aDates = this._parseDates(sDates);
-	for (var i=0;i<aDates.length;++i) {
-		var aDate = aDates[i];
-
-		if (aDate.length == 2) { // this is either a range or a month/day combo
-			if (aDate[0] instanceof Array) { // this is a range
-				this._addRenderer(YAHOO.widget.Calendar.RANGE,aDate,fnRender);
-			} else { // this is a month/day combo
-				this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,aDate,fnRender);
-			}
-		} else if (aDate.length == 3) {
-			this._addRenderer(YAHOO.widget.Calendar.DATE,aDate,fnRender);
-		}
-	}
-};
-
-/**
-* The private method used for adding cell renderers to the local render stack.
-* This method is called by other methods that set the renderer type prior to the method call.
-* @method _addRenderer
-* @private
-* @param	{String}	type		The type string that indicates the type of date renderer being added.
-*									Values are YAHOO.widget.Calendar.DATE, YAHOO.widget.Calendar.MONTH_DAY, YAHOO.widget.Calendar.WEEKDAY,
-*									YAHOO.widget.Calendar.RANGE, YAHOO.widget.Calendar.MONTH
-* @param	{Array}		aDates		An array of dates used to construct the renderer. The format varies based
-*									on the renderer type
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.Calendar.prototype._addRenderer = function(type, aDates, fnRender) {
-	var add = [type,aDates,fnRender];
-	this.renderStack.unshift(add);
-	this._renderStack = this.renderStack.concat();
-};
-
-/**
-* Adds a month to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the month passed to this method.
-* @method addMonthRenderer
-* @param	{Number}	month		The month (1-12) to associate with this renderer
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.Calendar.prototype.addMonthRenderer = function(month, fnRender) {
-	this._addRenderer(YAHOO.widget.Calendar.MONTH,[month],fnRender);
-};
-
-/**
-* Adds a weekday to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the weekday passed to this method.
-* @method addWeekdayRenderer
-* @param	{Number}	weekday		The weekday (0-6) to associate with this renderer
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.Calendar.prototype.addWeekdayRenderer = function(weekday, fnRender) {
-	this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
-};
-
-// END RENDERER METHODS
-
-// BEGIN CSS METHODS
-
-/**
-* Removes all styles from all body cells in the current calendar table.
-* @method clearAllBodyCellStyles
-* @param	{style}		The CSS class name to remove from all calendar body cells
-*/
-YAHOO.widget.Calendar.prototype.clearAllBodyCellStyles = function(style) {
-	for (var c=0;c<this.cells.length;++c) {
-		YAHOO.util.Dom.removeClass(this.cells[c],style);
-	}
-};
-
-// END CSS METHODS
-
-// BEGIN GETTER/SETTER METHODS
-/**
-* Sets the calendar's month explicitly
-* @method setMonth
-* @param {Number}	month		The numeric month, from 0 (January) to 11 (December)
-*/
-YAHOO.widget.Calendar.prototype.setMonth = function(month) {
-	var current = this.cfg.getProperty("pagedate");
-	current.setMonth(month);
-	this.cfg.setProperty("pagedate", current);
-};
-
-/**
-* Sets the calendar's year explicitly.
-* @method setYear
-* @param {Number}	year		The numeric 4-digit year
-*/
-YAHOO.widget.Calendar.prototype.setYear = function(year) {
-	var current = this.cfg.getProperty("pagedate");
-	current.setFullYear(year);
-	this.cfg.setProperty("pagedate", current);
-};
-
-/**
-* Gets the list of currently selected dates from the calendar.
-* @method getSelectedDates
-* @return {Date[]} An array of currently selected JavaScript Date objects.
-*/
-YAHOO.widget.Calendar.prototype.getSelectedDates = function() {
-	var returnDates = [];
-	var selected = this.cfg.getProperty("selected");
-
-	for (var d=0;d<selected.length;++d) {
-		var dateArray = selected[d];
-
-		var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
-		returnDates.push(date);
-	}
-
-	returnDates.sort( function(a,b) { return a-b; } );
-	return returnDates;
-};
-
-/// END GETTER/SETTER METHODS ///
-
-/**
-* Hides the Calendar's outer container from view.
-* @method hide
-*/
-YAHOO.widget.Calendar.prototype.hide = function() {
-	this.oDomContainer.style.display = "none";
-};
-
-/**
-* Shows the Calendar's outer container.
-* @method show
-*/
-YAHOO.widget.Calendar.prototype.show = function() {
-	this.oDomContainer.style.display = "block";
-};
-
-/**
-* Returns a string representing the current browser.
-* @property browser
-* @type String
-*/
-YAHOO.widget.Calendar.prototype.browser = function() {
-			var ua = navigator.userAgent.toLowerCase();
-				  if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
-					 return 'opera';
-				  } else if (ua.indexOf('msie 7')!=-1) { // IE7
-					 return 'ie7';
-				  } else if (ua.indexOf('msie') !=-1) { // IE
-					 return 'ie';
-				  } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
-					 return 'safari';
-				  } else if (ua.indexOf('gecko') != -1) { // Gecko
-					 return 'gecko';
-				  } else {
-					 return false;
-				  }
-			}();
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String}	A string representation of the Calendar object.
-*/
-YAHOO.widget.Calendar.prototype.toString = function() {
-	return "Calendar " + this.id;
-};
-
-/**
-* @namespace YAHOO.widget
-* @class Calendar_Core
-* @extends YAHOO.widget.Calendar
-* @deprecated The old Calendar_Core class is no longer necessary.
-*/
-YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;
-
-YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
-
-/**
-* YAHOO.widget.CalendarGroup is a special container class for YAHOO.widget.Calendar. This class facilitates
-* the ability to have multi-page calendar views that share a single dataset and are
-* dependent on each other.
-*
-* The calendar group instance will refer to each of its elements using a 0-based index.
-* For example, to construct the placeholder for a calendar group widget with id "cal1" and
-* containerId of "cal1Container", the markup would be as follows:
-*	<xmp>
-*		<div id="cal1Container_0"></div>
-*		<div id="cal1Container_1"></div>
-*	</xmp>
-* The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
-* @namespace YAHOO.widget
-* @class CalendarGroup
-* @constructor
-* @param {String}	id			The id of the table element that will represent the calendar widget
-* @param {String}	containerId	The id of the container div element that will wrap the calendar table
-* @param {Object}	config		The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.CalendarGroup = function(id, containerId, config) {
-	if (arguments.length > 0) {
-		this.init(id, containerId, config);
-	}
-};
-
-/**
-* Initializes the calendar group. All subclasses must call this method in order for the
-* group to be initialized properly.
-* @method init
-* @param {String}	id			The id of the table element that will represent the calendar widget
-* @param {String}	containerId	The id of the container div element that will wrap the calendar table
-* @param {Object}	config		The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.CalendarGroup.prototype.init = function(id, containerId, config) {
-	this.initEvents();
-	this.initStyles();
-
-	/**
-	* The collection of Calendar pages contained within the CalendarGroup
-	* @property pages
-	* @type YAHOO.widget.Calendar[]
-	*/
-	this.pages = [];
-
-	/**
-	* The unique id associated with the CalendarGroup
-	* @property id
-	* @type String
-	*/
-	this.id = id;
-
-	/**
-	* The unique id associated with the CalendarGroup container
-	* @property containerId
-	* @type String
-	*/
-	this.containerId = containerId;
-
-	/**
-	* The outer containing element for the CalendarGroup
-	* @property oDomContainer
-	* @type HTMLElement
-	*/
-	this.oDomContainer = document.getElementById(containerId);
-
-	YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_CONTAINER);
-	YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_MULTI_UP);
-
-	/**
-	* The Config object used to hold the configuration variables for the CalendarGroup
-	* @property cfg
-	* @type YAHOO.util.Config
-	*/
-	this.cfg = new YAHOO.util.Config(this);
-
-	/**
-	* The local object which contains the CalendarGroup's options
-	* @property Options
-	* @type Object
-	*/
-	this.Options = {};
-
-	/**
-	* The local object which contains the CalendarGroup's locale settings
-	* @property Locale
-	* @type Object
-	*/
-	this.Locale = {};
-
-	this.setupConfig();
-
-	if (config) {
-		this.cfg.applyConfig(config, true);
-	}
-
-	this.cfg.fireQueue();
-
-	// OPERA HACK FOR MISWRAPPED FLOATS
-	if (this.browser == "opera"){
-		var fixWidth = function() {
-			var startW = this.oDomContainer.offsetWidth;
-			var w = 0;
-			for (var p=0;p<this.pages.length;++p) {
-				var cal = this.pages[p];
-				w += cal.oDomContainer.offsetWidth;
-			}
-			if (w > 0) {
-				this.oDomContainer.style.width = w + "px";
-			}
-		};
-		this.renderEvent.subscribe(fixWidth,this,true);
-	}
-};
-
-
-YAHOO.widget.CalendarGroup.prototype.setupConfig = function() {
-	/**
-	* The number of pages to include in the CalendarGroup. This value can only be set once, in the CalendarGroup's constructor arguments.
-	* @config pages
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("pages", { value:2, validator:this.cfg.checkNumber, handler:this.configPages } );
-
-	/**
-	* The month/year representing the current visible Calendar date (mm/yyyy)
-	* @config pagedate
-	* @type String
-	* @default today's date
-	*/
-	this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );
-
-	/**
-	* The date or range of dates representing the current Calendar selection
-	* @config selected
-	* @type String
-	* @default []
-	*/
-	this.cfg.addProperty("selected", { value:[], handler:this.delegateConfig } );
-
-	/**
-	* The title to display above the CalendarGroup's month header
-	* @config title
-	* @type String
-	* @default ""
-	*/
-	this.cfg.addProperty("title", { value:"", handler:this.configTitle } );
-
-	/**
-	* Whether or not a close button should be displayed for this CalendarGroup
-	* @config close
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("close", { value:false, handler:this.configClose } );
-
-	/**
-	* Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
-	* @config iframe
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("iframe", { value:true, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-	/**
-	* The minimum selectable date in the current Calendar (mm/dd/yyyy)
-	* @config mindate
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("mindate", { value:null, handler:this.delegateConfig } );
-
-	/**
-	* The maximum selectable date in the current Calendar (mm/dd/yyyy)
-	* @config maxdate
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("maxdate", { value:null, handler:this.delegateConfig  } );
-
-	// Options properties
-
-	/**
-	* True if the Calendar should allow multiple selections. False by default.
-	* @config MULTI_SELECT
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("MULTI_SELECT",	{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-    /**
-    * True if the Calendar should allow selection of out-of-month dates. False by default.
-    * @config OOM_SELECT
-    * @type Boolean
-    * @default false
-    */
-    this.cfg.addProperty("OOM_SELECT",      { value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-	/**
-	* The weekday the week begins on. Default is 0 (Sunday).
-	* @config START_WEEKDAY
-	* @type number
-	* @default 0
-	*/
-	this.cfg.addProperty("START_WEEKDAY",	{ value:0, handler:this.delegateConfig, validator:this.cfg.checkNumber  } );
-
-	/**
-	* True if the Calendar should show weekday labels. True by default.
-	* @config SHOW_WEEKDAYS
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("SHOW_WEEKDAYS",	{ value:true, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-	/**
-	* True if the Calendar should show week row headers. False by default.
-	* @config SHOW_WEEK_HEADER
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-	/**
-	* True if the Calendar should show week row footers. False by default.
-	* @config SHOW_WEEK_FOOTER
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-	/**
-	* True if the Calendar should suppress weeks that are not a part of the current month. False by default.
-	* @config HIDE_BLANK_WEEKS
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
-	/**
-	* The image that should be used for the left navigation arrow.
-	* @config NAV_ARROW_LEFT
-	* @type String
-	* @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif"
-	*/
-	this.cfg.addProperty("NAV_ARROW_LEFT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.delegateConfig } );
-
-	/**
-	* The image that should be used for the left navigation arrow.
-	* @config NAV_ARROW_RIGHT
-	* @type String
-	* @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif"
-	*/
-	this.cfg.addProperty("NAV_ARROW_RIGHT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.delegateConfig } );
-
-	// Locale properties
-
-	/**
-	* The short month labels for the current locale.
-	* @config MONTHS_SHORT
-	* @type String[]
-	* @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
-	*/
-	this.cfg.addProperty("MONTHS_SHORT",	{ value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.delegateConfig } );
-
-	/**
-	* The long month labels for the current locale.
-	* @config MONTHS_LONG
-	* @type String[]
-	* @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
-	*/
-	this.cfg.addProperty("MONTHS_LONG",		{ value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.delegateConfig } );
-
-	/**
-	* The 1-character weekday labels for the current locale.
-	* @config WEEKDAYS_1CHAR
-	* @type String[]
-	* @default ["S", "M", "T", "W", "T", "F", "S"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_1CHAR",	{ value:["S", "M", "T", "W", "T", "F", "S"], handler:this.delegateConfig } );
-
-	/**
-	* The short weekday labels for the current locale.
-	* @config WEEKDAYS_SHORT
-	* @type String[]
-	* @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_SHORT",	{ value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.delegateConfig } );
-
-	/**
-	* The medium weekday labels for the current locale.
-	* @config WEEKDAYS_MEDIUM
-	* @type String[]
-	* @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_MEDIUM",	{ value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.delegateConfig } );
-
-	/**
-	* The long weekday labels for the current locale.
-	* @config WEEKDAYS_LONG
-	* @type String[]
-	* @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
-	*/
-	this.cfg.addProperty("WEEKDAYS_LONG",	{ value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.delegateConfig } );
-
-	/**
-	* The setting that determines which length of month labels should be used. Possible values are "short" and "long".
-	* @config LOCALE_MONTHS
-	* @type String
-	* @default "long"
-	*/
-	this.cfg.addProperty("LOCALE_MONTHS",	{ value:"long", handler:this.delegateConfig } );
-
-	/**
-	* The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
-	* @config LOCALE_WEEKDAYS
-	* @type String
-	* @default "short"
-	*/
-	this.cfg.addProperty("LOCALE_WEEKDAYS",	{ value:"short", handler:this.delegateConfig } );
-
-	/**
-	* The value used to delimit individual dates in a date string passed to various Calendar functions.
-	* @config DATE_DELIMITER
-	* @type String
-	* @default ","
-	*/
-	this.cfg.addProperty("DATE_DELIMITER",		{ value:",", handler:this.delegateConfig } );
-
-	/**
-	* The value used to delimit date fields in a date string passed to various Calendar functions.
-	* @config DATE_FIELD_DELIMITER
-	* @type String
-	* @default "/"
-	*/
-	this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.delegateConfig } );
-
-	/**
-	* The value used to delimit date ranges in a date string passed to various Calendar functions.
-	* @config DATE_RANGE_DELIMITER
-	* @type String
-	* @default "-"
-	*/
-	this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.delegateConfig } );
-
-	/**
-	* The position of the month in a month/year date string
-	* @config MY_MONTH_POSITION
-	* @type Number
-	* @default 1
-	*/
-	this.cfg.addProperty("MY_MONTH_POSITION",	{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the year in a month/year date string
-	* @config MY_YEAR_POSITION
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("MY_YEAR_POSITION",	{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the month in a month/day date string
-	* @config MD_MONTH_POSITION
-	* @type Number
-	* @default 1
-	*/
-	this.cfg.addProperty("MD_MONTH_POSITION",	{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the day in a month/year date string
-	* @config MD_DAY_POSITION
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("MD_DAY_POSITION",		{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the month in a month/day/year date string
-	* @config MDY_MONTH_POSITION
-	* @type Number
-	* @default 1
-	*/
-	this.cfg.addProperty("MDY_MONTH_POSITION",	{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the day in a month/day/year date string
-	* @config MDY_DAY_POSITION
-	* @type Number
-	* @default 2
-	*/
-	this.cfg.addProperty("MDY_DAY_POSITION",	{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-	/**
-	* The position of the year in a month/day/year date string
-	* @config MDY_YEAR_POSITION
-	* @type Number
-	* @default 3
-	*/
-	this.cfg.addProperty("MDY_YEAR_POSITION",	{ value:3, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
-};
-
-/**
-* Initializes CalendarGroup's built-in CustomEvents
-* @method initEvents
-*/
-YAHOO.widget.CalendarGroup.prototype.initEvents = function() {
-	var me = this;
-
-	/**
-	* Proxy subscriber to subscribe to the CalendarGroup's child Calendars' CustomEvents
-	* @method sub
-	* @private
-	* @param {Function} fn	The function to subscribe to this CustomEvent
-	* @param {Object}	obj	The CustomEvent's scope object
-	* @param {Boolean}	bOverride	Whether or not to apply scope correction
-	*/
-	var sub = function(fn, obj, bOverride) {
-		for (var p=0;p<me.pages.length;++p) {
-			var cal = me.pages[p];
-			cal[this.type + "Event"].subscribe(fn, obj, bOverride);
-		}
-	};
-
-	/**
-	* Proxy unsubscriber to unsubscribe from the CalendarGroup's child Calendars' CustomEvents
-	* @method unsub
-	* @private
-	* @param {Function} fn	The function to subscribe to this CustomEvent
-	* @param {Object}	obj	The CustomEvent's scope object
-	*/
-	var unsub = function(fn, obj) {
-		for (var p=0;p<me.pages.length;++p) {
-			var cal = me.pages[p];
-			cal[this.type + "Event"].unsubscribe(fn, obj);
-		}
-	};
-
-	/**
-	* Fired before a selection is made
-	* @event beforeSelectEvent
-	*/
-	this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");
-	this.beforeSelectEvent.subscribe = sub; this.beforeSelectEvent.unsubscribe = unsub;
-
-	/**
-	* Fired when a selection is made
-	* @event selectEvent
-	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
-	*/
-	this.selectEvent = new YAHOO.util.CustomEvent("select");
-	this.selectEvent.subscribe = sub; this.selectEvent.unsubscribe = unsub;
-
-	/**
-	* Fired before a selection is made
-	* @event beforeDeselectEvent
-	*/
-	this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");
-	this.beforeDeselectEvent.subscribe = sub; this.beforeDeselectEvent.unsubscribe = unsub;
-
-	/**
-	* Fired when a selection is made
-	* @event deselectEvent
-	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
-	*/
-	this.deselectEvent = new YAHOO.util.CustomEvent("deselect");
-	this.deselectEvent.subscribe = sub; this.deselectEvent.unsubscribe = unsub;
-
-	/**
-	* Fired when the Calendar page is changed
-	* @event changePageEvent
-	*/
-	this.changePageEvent = new YAHOO.util.CustomEvent("changePage");
-	this.changePageEvent.subscribe = sub; this.changePageEvent.unsubscribe = unsub;
-
-	/**
-	* Fired before the Calendar is rendered
-	* @event beforeRenderEvent
-	*/
-	this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
-	this.beforeRenderEvent.subscribe = sub; this.beforeRenderEvent.unsubscribe = unsub;
-
-	/**
-	* Fired when the Calendar is rendered
-	* @event renderEvent
-	*/
-	this.renderEvent = new YAHOO.util.CustomEvent("render");
-	this.renderEvent.subscribe = sub; this.renderEvent.unsubscribe = unsub;
-
-	/**
-	* Fired when the Calendar is reset
-	* @event resetEvent
-	*/
-	this.resetEvent = new YAHOO.util.CustomEvent("reset");
-	this.resetEvent.subscribe = sub; this.resetEvent.unsubscribe = unsub;
-
-	/**
-	* Fired when the Calendar is cleared
-	* @event clearEvent
-	*/
-	this.clearEvent = new YAHOO.util.CustomEvent("clear");
-	this.clearEvent.subscribe = sub; this.clearEvent.unsubscribe = unsub;
-
-};
-
-/**
-* The default Config handler for the "pages" property
-* @method configPages
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.configPages = function(type, args, obj) {
-	var pageCount = args[0];
-
-	for (var p=0;p<pageCount;++p) {
-		var calId = this.id + "_" + p;
-		var calContainerId = this.containerId + "_" + p;
-
-		var childConfig = this.cfg.getConfig();
-		childConfig.close = false;
-		childConfig.title = false;
-
-		var cal = this.constructChild(calId, calContainerId, childConfig);
-		var caldate = cal.cfg.getProperty("pagedate");
-		caldate.setMonth(caldate.getMonth()+p);
-		cal.cfg.setProperty("pagedate", caldate);
-
-		YAHOO.util.Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
-		YAHOO.util.Dom.addClass(cal.oDomContainer, "groupcal");
-
-		if (p===0) {
-			YAHOO.util.Dom.addClass(cal.oDomContainer, "first");
-		}
-
-		if (p==(pageCount-1)) {
-			YAHOO.util.Dom.addClass(cal.oDomContainer, "last");
-		}
-
-		cal.parent = this;
-		cal.index = p;
-
-		this.pages[this.pages.length] = cal;
-	}
-};
-
-/**
-* The default Config handler for the "pagedate" property
-* @method configPageDate
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.configPageDate = function(type, args, obj) {
-	var val = args[0];
-
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.cfg.setProperty("pagedate", val);
-		var calDate = cal.cfg.getProperty("pagedate");
-		calDate.setMonth(calDate.getMonth()+p);
-	}
-};
-
-/**
-* Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
-* @method delegateConfig
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.delegateConfig = function(type, args, obj) {
-	var val = args[0];
-	var cal;
-
-	for (var p=0;p<this.pages.length;p++) {
-		cal = this.pages[p];
-		cal.cfg.setProperty(type, val);
-	}
-};
-
-
-/**
-* Adds a function to all child Calendars within this CalendarGroup.
-* @method setChildFunction
-* @param {String}		fnName		The name of the function
-* @param {Function}		fn			The function to apply to each Calendar page object
-*/
-YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
-	var pageCount = this.cfg.getProperty("pages");
-
-	for (var p=0;p<pageCount;++p) {
-		this.pages[p][fnName] = fn;
-	}
-};
-
-/**
-* Calls a function within all child Calendars within this CalendarGroup.
-* @method callChildFunction
-* @param {String}		fnName		The name of the function
-* @param {Array}		args		The arguments to pass to the function
-*/
-YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {
-	var pageCount = this.cfg.getProperty("pages");
-
-	for (var p=0;p<pageCount;++p) {
-		var page = this.pages[p];
-		if (page[fnName]) {
-			var fn = page[fnName];
-			fn.call(page, args);
-		}
-	}
-};
-
-/**
-* Constructs a child calendar. This method can be overridden if a subclassed version of the default
-* calendar is to be used.
-* @method constructChild
-* @param {String}	id			The id of the table element that will represent the calendar widget
-* @param {String}	containerId	The id of the container div element that will wrap the calendar table
-* @param {Object}	config		The configuration object containing the Calendar's arguments
-* @return {YAHOO.widget.Calendar}	The YAHOO.widget.Calendar instance that is constructed
-*/
-YAHOO.widget.CalendarGroup.prototype.constructChild = function(id,containerId,config) {
-	var container = document.getElementById(containerId);
-	if (! container) {
-		container = document.createElement("div");
-		container.id = containerId;
-		this.oDomContainer.appendChild(container);
-	}
-	return new YAHOO.widget.Calendar(id,containerId,config);
-};
-
-
-/**
-* Sets the calendar group's month explicitly. This month will be set into the first
-* @method setMonth
-* page of the multi-page calendar, and all other months will be iterated appropriately.
-* @param {Number}	month		The numeric month, from 0 (January) to 11 (December)
-*/
-YAHOO.widget.CalendarGroup.prototype.setMonth = function(month) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.setMonth(month+p);
-	}
-};
-
-/**
-* Sets the calendar group's year explicitly. This year will be set into the first
-* @method setYear
-* page of the multi-page calendar, and all other months will be iterated appropriately.
-* @param {Number}	year		The numeric 4-digit year
-*/
-YAHOO.widget.CalendarGroup.prototype.setYear = function(year) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		var pageDate = cal.cfg.getProperty("pageDate");
-
-		if ((pageDate.getMonth()+1) == 1 && p>0) {
-			year+=1;
-		}
-		cal.setYear(year);
-	}
-};
-/**
-* Calls the render function of all child calendars within the group.
-* @method render
-*/
-YAHOO.widget.CalendarGroup.prototype.render = function() {
-	this.renderHeader();
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.render();
-	}
-	this.renderFooter();
-};
-
-/**
-* Selects a date or a collection of dates on the current calendar. This method, by default,
-* does not call the render method explicitly. Once selection has completed, render must be
-* called for the changes to be reflected visually.
-* @method select
-* @param	{String/Date/Date[]}	date	The date string of dates to select in the current calendar. Valid formats are
-*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
-*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
-*								This method can also take a JavaScript Date object or an array of Date objects.
-* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.CalendarGroup.prototype.select = function(date) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.select(date);
-	}
-	return this.getSelectedDates();
-};
-
-/**
-* Selects a date on the current calendar by referencing the index of the cell that should be selected.
-* This method is used to easily select a single cell (usually with a mouse click) without having to do
-* a full render. The selected style is applied to the cell directly.
-* @method selectCell
-* @param	{Number}	cellIndex	The index of the cell to select in the current calendar.
-* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.selectCell(cellIndex);
-	}
-	return this.getSelectedDates();
-};
-
-/**
-* Deselects a date or a collection of dates on the current calendar. This method, by default,
-* does not call the render method explicitly. Once deselection has completed, render must be
-* called for the changes to be reflected visually.
-* @method deselect
-* @param	{String/Date/Date[]}	date	The date string of dates to deselect in the current calendar. Valid formats are
-*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
-*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
-*								This method can also take a JavaScript Date object or an array of Date objects.
-* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.CalendarGroup.prototype.deselect = function(date) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.deselect(date);
-	}
-	return this.getSelectedDates();
-};
-
-/**
-* Deselects all dates on the current calendar.
-* @method deselectAll
-* @return {Date[]}		Array of JavaScript Date objects representing all individual dates that are currently selected.
-*						Assuming that this function executes properly, the return value should be an empty array.
-*						However, the empty array is returned for the sake of being able to check the selection status
-*						of the calendar.
-*/
-YAHOO.widget.CalendarGroup.prototype.deselectAll = function() {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.deselectAll();
-	}
-	return this.getSelectedDates();
-};
-
-/**
-* Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
-* This method is used to easily deselect a single cell (usually with a mouse click) without having to do
-* a full render. The selected style is removed from the cell directly.
-* @method deselectCell
-* @param	{Number}	cellIndex	The index of the cell to deselect in the current calendar.
-* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.CalendarGroup.prototype.deselectCell = function(cellIndex) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.deselectCell(cellIndex);
-	}
-	return this.getSelectedDates();
-};
-
-/**
-* Resets the calendar widget to the originally selected month and year, and
-* sets the calendar to the initial selection(s).
-* @method reset
-*/
-YAHOO.widget.CalendarGroup.prototype.reset = function() {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.reset();
-	}
-};
-
-/**
-* Clears the selected dates in the current calendar widget and sets the calendar
-* to the current month and year.
-* @method clear
-*/
-YAHOO.widget.CalendarGroup.prototype.clear = function() {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.clear();
-	}
-};
-
-/**
-* Navigates to the next month page in the calendar widget.
-* @method nextMonth
-*/
-YAHOO.widget.CalendarGroup.prototype.nextMonth = function() {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.nextMonth();
-	}
-};
-
-/**
-* Navigates to the previous month page in the calendar widget.
-* @method previousMonth
-*/
-YAHOO.widget.CalendarGroup.prototype.previousMonth = function() {
-	for (var p=this.pages.length-1;p>=0;--p) {
-		var cal = this.pages[p];
-		cal.previousMonth();
-	}
-};
-
-/**
-* Navigates to the next year in the currently selected month in the calendar widget.
-* @method nextYear
-*/
-YAHOO.widget.CalendarGroup.prototype.nextYear = function() {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.nextYear();
-	}
-};
-
-/**
-* Navigates to the previous year in the currently selected month in the calendar widget.
-* @method previousYear
-*/
-YAHOO.widget.CalendarGroup.prototype.previousYear = function() {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.previousYear();
-	}
-};
-
-
-/**
-* Gets the list of currently selected dates from the calendar.
-* @return			An array of currently selected JavaScript Date objects.
-* @type Date[]
-*/
-YAHOO.widget.CalendarGroup.prototype.getSelectedDates = function() {
-	var returnDates = [];
-	var selected = this.cfg.getProperty("selected");
-
-	for (var d=0;d<selected.length;++d) {
-		var dateArray = selected[d];
-
-		var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
-		returnDates.push(date);
-	}
-
-	returnDates.sort( function(a,b) { return a-b; } );
-	return returnDates;
-};
-
-/**
-* Adds a renderer to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the conditions specified in the date string for this renderer.
-* @method addRenderer
-* @param	{String}	sDates		A date string to associate with the specified renderer. Valid formats
-*									include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.CalendarGroup.prototype.addRenderer = function(sDates, fnRender) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.addRenderer(sDates, fnRender);
-	}
-};
-
-/**
-* Adds a month to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the month passed to this method.
-* @method addMonthRenderer
-* @param	{Number}	month		The month (1-12) to associate with this renderer
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.CalendarGroup.prototype.addMonthRenderer = function(month, fnRender) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.addMonthRenderer(month, fnRender);
-	}
-};
-
-/**
-* Adds a weekday to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the weekday passed to this method.
-* @method addWeekdayRenderer
-* @param	{Number}	weekday		The weekday (0-6) to associate with this renderer
-* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.CalendarGroup.prototype.addWeekdayRenderer = function(weekday, fnRender) {
-	for (var p=0;p<this.pages.length;++p) {
-		var cal = this.pages[p];
-		cal.addWeekdayRenderer(weekday, fnRender);
-	}
-};
-
-/**
-* Renders the header for the CalendarGroup.
-* @method renderHeader
-*/
-YAHOO.widget.CalendarGroup.prototype.renderHeader = function() {};
-
-/**
-* Renders a footer for the 2-up calendar container. By default, this method is
-* unimplemented.
-* @method renderFooter
-*/
-YAHOO.widget.CalendarGroup.prototype.renderFooter = function() {};
-
-/**
-* Adds the designated number of months to the current calendar month, and sets the current
-* calendar page date to the new month.
-* @method addMonths
-* @param {Number}	count	The number of months to add to the current calendar
-*/
-YAHOO.widget.CalendarGroup.prototype.addMonths = function(count) {
-	this.callChildFunction("addMonths", count);
-};
-
-
-/**
-* Subtracts the designated number of months from the current calendar month, and sets the current
-* calendar page date to the new month.
-* @method subtractMonths
-* @param {Number}	count	The number of months to subtract from the current calendar
-*/
-YAHOO.widget.CalendarGroup.prototype.subtractMonths = function(count) {
-	this.callChildFunction("subtractMonths", count);
-};
-
-/**
-* Adds the designated number of years to the current calendar, and sets the current
-* calendar page date to the new month.
-* @method addYears
-* @param {Number}	count	The number of years to add to the current calendar
-*/
-YAHOO.widget.CalendarGroup.prototype.addYears = function(count) {
-	this.callChildFunction("addYears", count);
-};
-
-/**
-* Subtcats the designated number of years from the current calendar, and sets the current
-* calendar page date to the new month.
-* @method subtractYears
-* @param {Number}	count	The number of years to subtract from the current calendar
-*/
-YAHOO.widget.CalendarGroup.prototype.subtractYears = function(count) {
-	this.callChildFunction("subtractYears", count);
-};
-
-/**
-* CSS class representing the container for the calendar
-* @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
-
-/**
-* CSS class representing the container for the calendar
-* @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_MULTI_UP = "multi";
-
-/**
-* CSS class representing the title for the 2-up calendar
-* @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_2UPTITLE = "title";
-
-/**
-* CSS class representing the close icon for the 2-up calendar
-* @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_2UPCLOSE = "close-icon";
-
-YAHOO.augment(YAHOO.widget.CalendarGroup, YAHOO.widget.Calendar, "buildDayLabel",
-																 "buildMonthLabel",
-																 "renderOutOfBoundsDate",
-																 "renderRowHeader",
-																 "renderRowFooter",
-																 "renderCellDefault",
-																 "styleCellDefault",
-																 "renderCellStyleHighlight1",
-																 "renderCellStyleHighlight2",
-																 "renderCellStyleHighlight3",
-																 "renderCellStyleHighlight4",
-																 "renderCellStyleToday",
-																 "renderCellStyleSelected",
-																 "renderCellNotThisMonth",
-																 "renderBodyCellRestricted",
-																 "initStyles",
-																 "configTitle",
-																 "configClose",
-																 "hide",
-																 "show",
-																 "browser");
-
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String}	A string representation of the CalendarGroup object.
-*/
-YAHOO.widget.CalendarGroup.prototype.toString = function() {
-	return "CalendarGroup " + this.id;
-};
-
-YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;
-
-/**
-* @class YAHOO.widget.Calendar2up
-* @extends YAHOO.widget.CalendarGroup
-* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
-*/
-YAHOO.widget.Calendar2up = function(id, containerId, config) {
-	this.init(id, containerId, config);
-};
-
-YAHOO.extend(YAHOO.widget.Calendar2up, YAHOO.widget.CalendarGroup);
-
-/**
-* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
-*/
-YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/**
+* Config is a utility used within an Object to allow the implementer to maintain a list of local configuration properties and listen for changes to those properties dynamically using CustomEvent. The initial values are also maintained so that the configuration can be reset at any given point to its initial state.
+* @namespace YAHOO.util
+* @class Config
+* @constructor
+* @param {Object}	owner	The owner Object to which this Config Object belongs
+*/
+YAHOO.util.Config = function(owner) {
+	if (owner) {
+		this.init(owner);
+	}
+};
+
+/**
+ * Constant representing the CustomEvent type for the config changed event.
+ * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
+ * @private
+ * @static
+ * @final
+ */
+YAHOO.util.Config.CONFIG_CHANGED_EVENT = "configChanged";
+
+/**
+ * Constant representing the boolean type string
+ * @property YAHOO.util.Config.BOOLEAN_TYPE
+ * @private
+ * @static
+ * @final
+ */
+YAHOO.util.Config.BOOLEAN_TYPE = "boolean";
+
+YAHOO.util.Config.prototype = {
+	
+	/**
+	* Object reference to the owner of this Config Object
+	* @property owner
+	* @type Object
+	*/
+	owner : null,
+
+	/**
+	* Boolean flag that specifies whether a queue is currently being executed
+	* @property queueInProgress
+	* @type Boolean
+	*/
+	queueInProgress : false,
+
+	/**
+	* Maintains the local collection of configuration property objects and their specified values
+	* @property config
+	* @private
+	* @type Object
+	*/ 
+	config : null,
+
+	/**
+	* Maintains the local collection of configuration property objects as they were initially applied.
+	* This object is used when resetting a property.
+	* @property initialConfig
+	* @private
+	* @type Object
+	*/ 
+	initialConfig : null,
+
+	/**
+	* Maintains the local, normalized CustomEvent queue
+	* @property eventQueue
+	* @private
+	* @type Object
+	*/ 
+	eventQueue : null,
+
+	/**
+	* Custom Event, notifying subscribers when Config properties are set (setProperty is called without the silent flag
+	* @event configChangedEvent
+	*/
+	configChangedEvent : null,
+
+	/**
+	* Validates that the value passed in is a Boolean.
+	* @method checkBoolean
+	* @param	{Object}	val	The value to validate
+	* @return	{Boolean}	true, if the value is valid
+	*/	
+	checkBoolean: function(val) {
+		return (typeof val == YAHOO.util.Config.BOOLEAN_TYPE);
+	},
+
+	/**
+	* Validates that the value passed in is a number.
+	* @method checkNumber
+	* @param	{Object}	val	The value to validate
+	* @return	{Boolean}	true, if the value is valid
+	*/
+	checkNumber: function(val) {
+		return (!isNaN(val));
+	},
+
+	/**
+	* Fires a configuration property event using the specified value. 
+	* @method fireEvent
+	* @private
+	* @param {String}	key			The configuration property's name
+	* @param {value}	Object		The value of the correct type for the property
+	*/ 
+	fireEvent : function( key, value ) {
+		var property = this.config[key];
+
+		if (property && property.event) {
+			property.event.fire(value);
+		}	
+	},
+
+	/**
+	* Adds a property to the Config Object's private config hash.
+	* @method addProperty
+	* @param {String}	key	The configuration property's name
+	* @param {Object}	propertyObject	The Object containing all of this property's arguments
+	*/
+	addProperty : function( key, propertyObject ) {
+		key = key.toLowerCase();
+
+		this.config[key] = propertyObject;
+
+		propertyObject.event = new YAHOO.util.CustomEvent(key, this.owner);
+		propertyObject.key = key;
+
+		if (propertyObject.handler) {
+			propertyObject.event.subscribe(propertyObject.handler, this.owner);
+		}
+
+		this.setProperty(key, propertyObject.value, true);
+		
+		if (! propertyObject.suppressEvent) {
+			this.queueProperty(key, propertyObject.value);
+		}
+		
+	},
+
+	/**
+	* Returns a key-value configuration map of the values currently set in the Config Object.
+	* @method getConfig
+	* @return {Object} The current config, represented in a key-value map
+	*/
+	getConfig : function() {
+		var cfg = {};
+			
+		for (var prop in this.config) {
+			var property = this.config[prop];
+			if (property && property.event) {
+				cfg[prop] = property.value;
+			}
+		}
+		
+		return cfg;
+	},
+
+	/**
+	* Returns the value of specified property.
+	* @method getProperty
+	* @param {String} key	The name of the property
+	* @return {Object}		The value of the specified property
+	*/
+	getProperty : function(key) {
+		var property = this.config[key.toLowerCase()];
+		if (property && property.event) {
+			return property.value;
+		} else {
+			return undefined;
+		}
+	},
+
+	/**
+	* Resets the specified property's value to its initial value.
+	* @method resetProperty
+	* @param {String} key	The name of the property
+	* @return {Boolean} True is the property was reset, false if not
+	*/
+	resetProperty : function(key) {
+		key = key.toLowerCase();
+
+		var property = this.config[key];
+		if (property && property.event) {
+			if (this.initialConfig[key] && !YAHOO.lang.isUndefined(this.initialConfig[key]))	{
+				this.setProperty(key, this.initialConfig[key]);
+			}
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Sets the value of a property. If the silent property is passed as true, the property's event will not be fired.
+	* @method setProperty
+	* @param {String} key		The name of the property
+	* @param {String} value		The value to set the property to
+	* @param {Boolean} silent	Whether the value should be set silently, without firing the property event.
+	* @return {Boolean}			True, if the set was successful, false if it failed.
+	*/
+	setProperty : function(key, value, silent) {
+		key = key.toLowerCase();
+
+		if (this.queueInProgress && ! silent) {
+			this.queueProperty(key,value); // Currently running through a queue... 
+			return true;
+		} else {
+			var property = this.config[key];
+			if (property && property.event) {
+				if (property.validator && ! property.validator(value)) { // validator
+					return false;
+				} else {
+					property.value = value;
+					if (! silent) {
+						this.fireEvent(key, value);
+						this.configChangedEvent.fire([key, value]);
+					}
+					return true;
+				}
+			} else {
+				return false;
+			}
+		}
+	},
+
+	/**
+	* Sets the value of a property and queues its event to execute. If the event is already scheduled to execute, it is
+	* moved from its current position to the end of the queue.
+	* @method queueProperty
+	* @param {String} key	The name of the property
+	* @param {String} value	The value to set the property to
+	* @return {Boolean}		true, if the set was successful, false if it failed.
+	*/	
+	queueProperty : function(key, value) {
+		key = key.toLowerCase();
+
+		var property = this.config[key];
+							
+		if (property && property.event) {
+			if (!YAHOO.lang.isUndefined(value) && property.validator && ! property.validator(value)) { // validator
+				return false;
+			} else {
+
+				if (!YAHOO.lang.isUndefined(value)) {
+					property.value = value;
+				} else {
+					value = property.value;
+				}
+
+				var foundDuplicate = false;
+				var iLen = this.eventQueue.length;
+				for (var i=0; i < iLen; i++) {
+					var queueItem = this.eventQueue[i];
+
+					if (queueItem) {
+						var queueItemKey = queueItem[0];
+						var queueItemValue = queueItem[1];
+						
+						if (queueItemKey == key) {
+							// found a dupe... push to end of queue, null current item, and break
+							this.eventQueue[i] = null;
+							this.eventQueue.push([key, (!YAHOO.lang.isUndefined(value) ? value : queueItemValue)]);
+							foundDuplicate = true;
+							break;
+						}
+					}
+				}
+				
+				if (! foundDuplicate && !YAHOO.lang.isUndefined(value)) { // this is a refire, or a new property in the queue
+					this.eventQueue.push([key, value]);
+				}
+			}
+
+			if (property.supercedes) {
+				var sLen = property.supercedes.length;
+				for (var s=0; s < sLen; s++) {
+					var supercedesCheck = property.supercedes[s];
+					var qLen = this.eventQueue.length;
+					for (var q=0; q < qLen; q++) {
+						var queueItemCheck = this.eventQueue[q];
+
+						if (queueItemCheck) {
+							var queueItemCheckKey = queueItemCheck[0];
+							var queueItemCheckValue = queueItemCheck[1];
+							
+							if ( queueItemCheckKey == supercedesCheck.toLowerCase() ) {
+								this.eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
+								this.eventQueue[q] = null;
+								break;
+							}
+						}
+					}
+				}
+			}
+
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Fires the event for a property using the property's current value.
+	* @method refireEvent
+	* @param {String} key	The name of the property
+	*/
+	refireEvent : function(key) {
+		key = key.toLowerCase();
+
+		var property = this.config[key];
+		if (property && property.event && !YAHOO.lang.isUndefined(property.value)) {
+			if (this.queueInProgress) {
+				this.queueProperty(key);
+			} else {
+				this.fireEvent(key, property.value);
+			}
+		}
+	},
+
+	/**
+	* Applies a key-value Object literal to the configuration, replacing any existing values, and queueing the property events.
+	* Although the values will be set, fireQueue() must be called for their associated events to execute.
+	* @method applyConfig
+	* @param {Object}	userConfig	The configuration Object literal
+	* @param {Boolean}	init		When set to true, the initialConfig will be set to the userConfig passed in, so that calling a reset will reset the properties to the passed values.
+	*/
+	applyConfig : function(userConfig, init) {
+		if (init) {
+			this.initialConfig = userConfig;
+		}
+		for (var prop in userConfig) {
+			this.queueProperty(prop, userConfig[prop]);
+		}
+	},
+
+	/**
+	* Refires the events for all configuration properties using their current values.
+	* @method refresh
+	*/
+	refresh : function() {
+		for (var prop in this.config) {
+			this.refireEvent(prop);
+		}
+	},
+
+	/**
+	* Fires the normalized list of queued property change events
+	* @method fireQueue
+	*/
+	fireQueue : function() {
+		this.queueInProgress = true;
+		for (var i=0;i<this.eventQueue.length;i++) {
+			var queueItem = this.eventQueue[i];
+			if (queueItem) {
+				var key = queueItem[0];
+				var value = queueItem[1];
+				
+				var property = this.config[key];
+				property.value = value;
+
+				this.fireEvent(key,value);
+			}
+		}
+		
+		this.queueInProgress = false;
+		this.eventQueue = [];
+	},
+
+	/**
+	* Subscribes an external handler to the change event for any given property. 
+	* @method subscribeToConfigEvent
+	* @param {String}	key			The property name
+	* @param {Function}	handler		The handler function to use subscribe to the property's event
+	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
+	* @param {Boolean}	override	Optional. If true, will override "this" within the handler to map to the scope Object passed into the method.
+	* @return {Boolean}				True, if the subscription was successful, otherwise false.
+	*/	
+	subscribeToConfigEvent : function(key, handler, obj, override) {
+		var property = this.config[key.toLowerCase()];
+		if (property && property.event) {
+			if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, obj)) {
+				property.event.subscribe(handler, obj, override);
+			}
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Unsubscribes an external handler from the change event for any given property. 
+	* @method unsubscribeFromConfigEvent
+	* @param {String}	key			The property name
+	* @param {Function}	handler		The handler function to use subscribe to the property's event
+	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
+	* @return {Boolean}				True, if the unsubscription was successful, otherwise false.
+	*/
+	unsubscribeFromConfigEvent : function(key, handler, obj) {
+		var property = this.config[key.toLowerCase()];
+		if (property && property.event) {
+			return property.event.unsubscribe(handler, obj);
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Returns a string representation of the Config object
+	* @method toString
+	* @return {String}	The Config object in string format.
+	*/
+	toString : function() {
+		var output = "Config";
+		if (this.owner) {
+			output += " [" + this.owner.toString() + "]";
+		}
+		return output;
+	},
+
+	/**
+	* Returns a string representation of the Config object's current CustomEvent queue
+	* @method outputEventQueue
+	* @return {String}	The string list of CustomEvents currently queued for execution
+	*/
+	outputEventQueue : function() {
+		var output = "";
+		for (var q=0;q<this.eventQueue.length;q++) {
+			var queueItem = this.eventQueue[q];
+			if (queueItem) {
+				output += queueItem[0] + "=" + queueItem[1] + ", ";
+			}
+		}
+		return output;
+	}
+};
+
+
+/**
+* Initializes the configuration Object and all of its local members.
+* @method init
+* @param {Object}	owner	The owner Object to which this Config Object belongs
+*/
+YAHOO.util.Config.prototype.init = function(owner) {
+	this.owner = owner;
+	this.configChangedEvent = new YAHOO.util.CustomEvent(YAHOO.util.CONFIG_CHANGED_EVENT, this);
+	this.queueInProgress = false;
+	this.config = {};
+	this.initialConfig = {};
+	this.eventQueue = [];
+};
+
+/**
+* Checks to determine if a particular function/Object pair are already subscribed to the specified CustomEvent
+* @method YAHOO.util.Config.alreadySubscribed
+* @static
+* @param {YAHOO.util.CustomEvent} evt	The CustomEvent for which to check the subscriptions
+* @param {Function}	fn	The function to look for in the subscribers list
+* @param {Object}	obj	The execution scope Object for the subscription
+* @return {Boolean}	true, if the function/Object pair is already subscribed to the CustomEvent passed in
+*/
+YAHOO.util.Config.alreadySubscribed = function(evt, fn, obj) {
+	for (var e=0;e<evt.subscribers.length;e++) {
+		var subsc = evt.subscribers[e];
+		if (subsc && subsc.obj == obj && subsc.fn == fn) {
+			return true;
+		}
+	}
+	return false;
+};
+
+/**
+* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
+* used for adding, subtracting, and comparing dates.
+* @namespace YAHOO.widget
+* @class DateMath
+*/
+YAHOO.widget.DateMath = {
+	/**
+	* Constant field representing Day
+	* @property DAY
+	* @static
+	* @final
+	* @type String
+	*/
+	DAY : "D",
+
+	/**
+	* Constant field representing Week
+	* @property WEEK
+	* @static
+	* @final
+	* @type String
+	*/
+	WEEK : "W",
+
+	/**
+	* Constant field representing Year
+	* @property YEAR
+	* @static
+	* @final
+	* @type String
+	*/
+	YEAR : "Y",
+
+	/**
+	* Constant field representing Month
+	* @property MONTH
+	* @static
+	* @final
+	* @type String
+	*/
+	MONTH : "M",
+
+	/**
+	* Constant field representing one day, in milliseconds
+	* @property ONE_DAY_MS
+	* @static
+	* @final
+	* @type Number
+	*/
+	ONE_DAY_MS : 1000*60*60*24,
+
+	/**
+	* Adds the specified amount of time to the this instance.
+	* @method add
+	* @param {Date} date	The JavaScript Date object to perform addition on
+	* @param {String} field	The field constant to be used for performing addition.
+	* @param {Number} amount	The number of units (measured in the field constant) to add to the date.
+	* @return {Date} The resulting Date object
+	*/
+	add : function(date, field, amount) {
+		var d = new Date(date.getTime());
+		switch (field) {
+			case this.MONTH:
+				var newMonth = date.getMonth() + amount;
+				var years = 0;
+
+
+				if (newMonth < 0) {
+					while (newMonth < 0) {
+						newMonth += 12;
+						years -= 1;
+					}
+				} else if (newMonth > 11) {
+					while (newMonth > 11) {
+						newMonth -= 12;
+						years += 1;
+					}
+				}
+				
+				d.setMonth(newMonth);
+				d.setFullYear(date.getFullYear() + years);
+				break;
+			case this.DAY:
+				d.setDate(date.getDate() + amount);
+				break;
+			case this.YEAR:
+				d.setFullYear(date.getFullYear() + amount);
+				break;
+			case this.WEEK:
+				d.setDate(date.getDate() + (amount * 7));
+				break;
+		}
+		return d;
+	},
+
+	/**
+	* Subtracts the specified amount of time from the this instance.
+	* @method subtract
+	* @param {Date} date	The JavaScript Date object to perform subtraction on
+	* @param {Number} field	The this field constant to be used for performing subtraction.
+	* @param {Number} amount	The number of units (measured in the field constant) to subtract from the date.
+	* @return {Date} The resulting Date object
+	*/
+	subtract : function(date, field, amount) {
+		return this.add(date, field, (amount*-1));
+	},
+
+	/**
+	* Determines whether a given date is before another date on the calendar.
+	* @method before
+	* @param {Date} date		The Date object to compare with the compare argument
+	* @param {Date} compareTo	The Date object to use for the comparison
+	* @return {Boolean} true if the date occurs before the compared date; false if not.
+	*/
+	before : function(date, compareTo) {
+		var ms = compareTo.getTime();
+		if (date.getTime() < ms) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Determines whether a given date is after another date on the calendar.
+	* @method after
+	* @param {Date} date		The Date object to compare with the compare argument
+	* @param {Date} compareTo	The Date object to use for the comparison
+	* @return {Boolean} true if the date occurs after the compared date; false if not.
+	*/
+	after : function(date, compareTo) {
+		var ms = compareTo.getTime();
+		if (date.getTime() > ms) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Determines whether a given date is between two other dates on the calendar.
+	* @method between
+	* @param {Date} date		The date to check for
+	* @param {Date} dateBegin	The start of the range
+	* @param {Date} dateEnd		The end of the range
+	* @return {Boolean} true if the date occurs between the compared dates; false if not.
+	*/
+	between : function(date, dateBegin, dateEnd) {
+		if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+	
+	/**
+	* Retrieves a JavaScript Date object representing January 1 of any given year.
+	* @method getJan1
+	* @param {Number} calendarYear		The calendar year for which to retrieve January 1
+	* @return {Date}	January 1 of the calendar year specified.
+	*/
+	getJan1 : function(calendarYear) {
+		return new Date(calendarYear,0,1); 
+	},
+
+	/**
+	* Calculates the number of days the specified date is from January 1 of the specified calendar year.
+	* Passing January 1 to this function would return an offset value of zero.
+	* @method getDayOffset
+	* @param {Date}	date	The JavaScript date for which to find the offset
+	* @param {Number} calendarYear	The calendar year to use for determining the offset
+	* @return {Number}	The number of days since January 1 of the given year
+	*/
+	getDayOffset : function(date, calendarYear) {
+		var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
+		
+		// Find the number of days the passed in date is away from the calendar year start
+		var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
+		return dayOffset;
+	},
+
+	/**
+	* Calculates the week number for the given date. This function assumes that week 1 is the
+	* week in which January 1 appears, regardless of whether the week consists of a full 7 days.
+	* The calendar year can be specified to help find what a the week number would be for a given
+	* date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
+	* week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
+	* easily.
+	* @method getWeekNumber
+	* @param {Date}	date	The JavaScript date for which to find the week number
+	* @param {Number} calendarYear	OPTIONAL - The calendar year to use for determining the week number. Default is
+	*											the calendar year of parameter "date".
+	* @param {Number} weekStartsOn	OPTIONAL - The integer (0-6) representing which day a week begins on. Default is 0 (for Sunday).
+	* @return {Number}	The week number of the given date.
+	*/
+	getWeekNumber : function(date, calendarYear) {
+		date = this.clearTime(date);
+		var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
+
+		var jan1 = new Date(nearestThurs.getFullYear(),0,1);
+		var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
+
+		var weekNum = Math.ceil((dayOfYear)/ 7);
+		return weekNum;
+	},
+
+	/**
+	* Determines if a given week overlaps two different years.
+	* @method isYearOverlapWeek
+	* @param {Date}	weekBeginDate	The JavaScript Date representing the first day of the week.
+	* @return {Boolean}	true if the date overlaps two different years.
+	*/
+	isYearOverlapWeek : function(weekBeginDate) {
+		var overlaps = false;
+		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
+		if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
+			overlaps = true;
+		}
+		return overlaps;
+	},
+
+	/**
+	* Determines if a given week overlaps two different months.
+	* @method isMonthOverlapWeek
+	* @param {Date}	weekBeginDate	The JavaScript Date representing the first day of the week.
+	* @return {Boolean}	true if the date overlaps two different months.
+	*/
+	isMonthOverlapWeek : function(weekBeginDate) {
+		var overlaps = false;
+		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
+		if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
+			overlaps = true;
+		}
+		return overlaps;
+	},
+
+	/**
+	* Gets the first day of a month containing a given date.
+	* @method findMonthStart
+	* @param {Date}	date	The JavaScript Date used to calculate the month start
+	* @return {Date}		The JavaScript Date representing the first day of the month
+	*/
+	findMonthStart : function(date) {
+		var start = new Date(date.getFullYear(), date.getMonth(), 1);
+		return start;
+	},
+
+	/**
+	* Gets the last day of a month containing a given date.
+	* @method findMonthEnd
+	* @param {Date}	date	The JavaScript Date used to calculate the month end
+	* @return {Date}		The JavaScript Date representing the last day of the month
+	*/
+	findMonthEnd : function(date) {
+		var start = this.findMonthStart(date);
+		var nextMonth = this.add(start, this.MONTH, 1);
+		var end = this.subtract(nextMonth, this.DAY, 1);
+		return end;
+	},
+
+	/**
+	* Clears the time fields from a given date, effectively setting the time to 12 noon.
+	* @method clearTime
+	* @param {Date}	date	The JavaScript Date for which the time fields will be cleared
+	* @return {Date}		The JavaScript Date cleared of all time fields
+	*/
+	clearTime : function(date) {
+		date.setHours(12,0,0,0);
+		return date;
+	}
+};
+
+/**
+* The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month ("one-up") or two-month ("two-up") interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
+* @module    calendar
+* @title     Calendar
+* @namespace YAHOO.widget
+* @requires  yahoo,dom,event
+*/
+
+/**
+* Calendar is the base class for the Calendar widget. In its most basic
+* implementation, it has the ability to render a calendar widget on the page
+* that can be manipulated to select a single date, move back and forth between
+* months and years.
+* <p>To construct the placeholder for the calendar widget, the code is as
+* follows:
+*	<xmp>
+*		<div id="cal1Container"></div>
+*	</xmp>
+* Note that the table can be replaced with any kind of element.
+* </p>
+* @namespace YAHOO.widget
+* @class Calendar
+* @constructor
+* @param {String}	id			The id of the table element that will represent the calendar widget
+* @param {String}	containerId	The id of the container div element that will wrap the calendar table
+* @param {Object}	config		The configuration object containing the Calendar's arguments
+*/
+YAHOO.widget.Calendar = function(id, containerId, config) {
+	this.init(id, containerId, config);
+};
+
+/**
+* The path to be used for images loaded for the Calendar
+* @property YAHOO.widget.Calendar.IMG_ROOT
+* @static
+* @deprecated	You can now customize images by overriding the calclose, calnavleft and calnavright default CSS classes for the close icon, left arrow and right arrow respectively
+* @type String
+*/
+YAHOO.widget.Calendar.IMG_ROOT = null;
+
+/**
+* Type constant used for renderers to represent an individual date (M/D/Y)
+* @property YAHOO.widget.Calendar.DATE
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.DATE = "D";
+
+/**
+* Type constant used for renderers to represent an individual date across any year (M/D)
+* @property YAHOO.widget.Calendar.MONTH_DAY
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.MONTH_DAY = "MD";
+
+/**
+* Type constant used for renderers to represent a weekday
+* @property YAHOO.widget.Calendar.WEEKDAY
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.WEEKDAY = "WD";
+
+/**
+* Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
+* @property YAHOO.widget.Calendar.RANGE
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.RANGE = "R";
+
+/**
+* Type constant used for renderers to represent a month across any year
+* @property YAHOO.widget.Calendar.MONTH
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.MONTH = "M";
+
+/**
+* Constant that represents the total number of date cells that are displayed in a given month
+* @property YAHOO.widget.Calendar.DISPLAY_DAYS
+* @static
+* @final
+* @type Number
+*/
+YAHOO.widget.Calendar.DISPLAY_DAYS = 42;
+
+/**
+* Constant used for halting the execution of the remainder of the render stack
+* @property YAHOO.widget.Calendar.STOP_RENDER
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.STOP_RENDER = "S";
+
+/**
+* Constant used to represent short date field string formats (e.g. Tu or Feb)
+* @property YAHOO.widget.Calendar.SHORT
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.SHORT = "short";
+
+/**
+* Constant used to represent long date field string formats (e.g. Monday or February)
+* @property YAHOO.widget.Calendar.LONG
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.LONG = "long";
+
+/**
+* Constant used to represent medium date field string formats (e.g. Mon)
+* @property YAHOO.widget.Calendar.MEDIUM
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.MEDIUM = "medium";
+
+/**
+* Constant used to represent single character date field string formats (e.g. M, T, W)
+* @property YAHOO.widget.Calendar.ONE_CHAR
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Calendar.ONE_CHAR = "1char";
+
+/**
+* The set of default Config property keys and values for the Calendar
+* @property YAHOO.widget.Calendar._DEFAULT_CONFIG
+* @final
+* @static
+* @private
+* @type Object
+*/
+YAHOO.widget.Calendar._DEFAULT_CONFIG = {
+	PAGEDATE : {key:"pagedate", value:new Date()},
+	SELECTED : {key:"selected", value:[]},
+	TITLE : {key:"title", value:""},
+	CLOSE : {key:"close", value:false},
+	IFRAME : {key:"iframe", value:true},
+	MINDATE : {key:"mindate", value:null},
+	MAXDATE : {key:"maxdate", value:null},
+	MULTI_SELECT : {key:"multi_select",	value:false},
+	START_WEEKDAY : {key:"start_weekday", value:0},
+	SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
+	SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
+	SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
+	HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
+	NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
+	NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
+	MONTHS_SHORT : {key:"months_short",	value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
+	MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
+	WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
+	WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
+	WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
+	WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
+	LOCALE_MONTHS:{key:"locale_months", value:"long"},
+	LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
+	DATE_DELIMITER:{key:"date_delimiter", value:","},
+	DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
+	DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
+	MY_MONTH_POSITION:{key:"my_month_position", value:1},
+	MY_YEAR_POSITION:{key:"my_year_position", value:2},
+	MD_MONTH_POSITION:{key:"md_month_position", value:1},
+	MD_DAY_POSITION:{key:"md_day_position", value:2},
+	MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
+	MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
+	MDY_YEAR_POSITION:{key:"mdy_year_position", value:3}
+};
+
+/**
+* The set of Custom Event types supported by the Calendar
+* @property YAHOO.widget.Calendar._EVENT_TYPES
+* @final
+* @static
+* @private
+* @type Object
+*/
+YAHOO.widget.Calendar._EVENT_TYPES = {
+	BEFORE_SELECT : "beforeSelect", 
+	SELECT : "select",
+	BEFORE_DESELECT : "beforeDeselect",
+	DESELECT : "deselect",
+	CHANGE_PAGE : "changePage",
+	BEFORE_RENDER : "beforeRender",
+	RENDER : "render",
+	RESET : "reset",
+	CLEAR : "clear"
+};
+
+/**
+* Collection of Default Style constants for the Calendar
+* @property YAHOO.widget.Calendar._STYLES
+* @final
+* @static
+* @private
+* @type Object
+*/
+YAHOO.widget.Calendar._STYLES = {
+	CSS_ROW_HEADER: "calrowhead",
+	CSS_ROW_FOOTER: "calrowfoot",
+	CSS_CELL : "calcell",
+	CSS_CELL_SELECTOR : "selector",
+	CSS_CELL_SELECTED : "selected",
+	CSS_CELL_SELECTABLE : "selectable",
+	CSS_CELL_RESTRICTED : "restricted",
+	CSS_CELL_TODAY : "today",
+	CSS_CELL_OOM : "oom",
+	CSS_CELL_OOB : "previous",
+	CSS_HEADER : "calheader",
+	CSS_HEADER_TEXT : "calhead",
+	CSS_BODY : "calbody",
+	CSS_WEEKDAY_CELL : "calweekdaycell",
+	CSS_WEEKDAY_ROW : "calweekdayrow",
+	CSS_FOOTER : "calfoot",
+	CSS_CALENDAR : "yui-calendar",
+	CSS_SINGLE : "single",
+	CSS_CONTAINER : "yui-calcontainer",
+	CSS_NAV_LEFT : "calnavleft",
+	CSS_NAV_RIGHT : "calnavright",
+	CSS_CLOSE : "calclose",
+	CSS_CELL_TOP : "calcelltop",
+	CSS_CELL_LEFT : "calcellleft",
+	CSS_CELL_RIGHT : "calcellright",
+	CSS_CELL_BOTTOM : "calcellbottom",
+	CSS_CELL_HOVER : "calcellhover",
+	CSS_CELL_HIGHLIGHT1 : "highlight1",
+	CSS_CELL_HIGHLIGHT2 : "highlight2",
+	CSS_CELL_HIGHLIGHT3 : "highlight3",
+	CSS_CELL_HIGHLIGHT4 : "highlight4"
+};
+
+YAHOO.widget.Calendar.prototype = {
+
+	/**
+	* The configuration object used to set up the calendars various locale and style options.
+	* @property Config
+	* @private
+	* @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
+	* @type Object
+	*/
+	Config : null,
+
+	/**
+	* The parent CalendarGroup, only to be set explicitly by the parent group
+	* @property parent
+	* @type CalendarGroup
+	*/	
+	parent : null,
+
+	/**
+	* The index of this item in the parent group
+	* @property index
+	* @type Number
+	*/
+	index : -1,
+
+	/**
+	* The collection of calendar table cells
+	* @property cells
+	* @type HTMLTableCellElement[]
+	*/
+	cells : null,
+	
+	/**
+	* The collection of calendar cell dates that is parallel to the cells collection. The array contains dates field arrays in the format of [YYYY, M, D].
+	* @property cellDates
+	* @type Array[](Number[])
+	*/
+	cellDates : null,
+
+	/**
+	* The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page.
+	* @property id
+	* @type String
+	*/
+	id : null,
+
+	/**
+	* The DOM element reference that points to this calendar's container element. The calendar will be inserted into this element when the shell is rendered.
+	* @property oDomContainer
+	* @type HTMLElement
+	*/
+	oDomContainer : null,
+
+	/**
+	* A Date object representing today's date.
+	* @property today
+	* @type Date
+	*/
+	today : null,
+
+	/**
+	* The list of render functions, along with required parameters, used to render cells. 
+	* @property renderStack
+	* @type Array[]
+	*/
+	renderStack : null,
+
+	/**
+	* A copy of the initial render functions created before rendering.
+	* @property _renderStack
+	* @private
+	* @type Array
+	*/
+	_renderStack : null,
+
+	/**
+	* The private list of initially selected dates.
+	* @property _selectedDates
+	* @private
+	* @type Array
+	*/
+	_selectedDates : null,
+
+	/**
+	* A map of DOM event handlers to attach to cells associated with specific CSS class names
+	* @property domEventMap
+	* @type Object
+	*/
+	domEventMap : null
+};
+
+
+
+/**
+* Initializes the Calendar widget.
+* @method init
+* @param {String}	id			The id of the table element that will represent the calendar widget
+* @param {String}	containerId	The id of the container div element that will wrap the calendar table
+* @param {Object}	config		The configuration object containing the Calendar's arguments
+*/
+YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
+	this.initEvents();
+	this.today = new Date();
+	YAHOO.widget.DateMath.clearTime(this.today);
+
+	this.id = id;
+	this.oDomContainer = document.getElementById(containerId);
+
+	/**
+	* The Config object used to hold the configuration variables for the Calendar
+	* @property cfg
+	* @type YAHOO.util.Config
+	*/
+	this.cfg = new YAHOO.util.Config(this);
+	
+	/**
+	* The local object which contains the Calendar's options
+	* @property Options
+	* @type Object
+	*/
+	this.Options = {};
+
+	/**
+	* The local object which contains the Calendar's locale settings
+	* @property Locale
+	* @type Object
+	*/
+	this.Locale = {};
+
+	this.initStyles();
+
+	YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);	
+	YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
+
+	this.cellDates = [];
+	this.cells = [];
+	this.renderStack = [];
+	this._renderStack = [];
+
+	this.setupConfig();
+	
+	if (config) {
+		this.cfg.applyConfig(config, true);
+	}
+	
+	this.cfg.fireQueue();
+};
+
+/**
+* Renders the built-in IFRAME shim for the IE6 and below
+* @method configIframe
+*/
+YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
+	var useIframe = args[0];
+
+	if (!this.parent) {
+		if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
+			if (useIframe) {
+				var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");
+
+				if (this.browser == "ie" && (pos == "absolute" || pos == "relative")) {
+					if (! YAHOO.util.Dom.inDocument(this.iframe)) {
+						this.iframe = document.createElement("iframe");
+						this.iframe.src = "javascript:false;";
+						YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
+						this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
+					}
+				}
+			} else {
+				if (this.iframe) {
+					if (this.iframe.parentNode) {
+						this.iframe.parentNode.removeChild(this.iframe);
+					}
+					this.iframe = null;
+				}
+			}
+		}
+	}
+};
+
+/**
+* Default handler for the "title" property
+* @method configTitle
+*/
+YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
+	var title = args[0];
+	var close = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.CLOSE.key);
+	
+	var titleDiv;
+
+	if (title && title !== "") {
+		titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
+		titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
+		titleDiv.innerHTML = title;
+		this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
+		YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
+	} else {
+		titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
+
+		if (titleDiv) {
+			YAHOO.util.Event.purgeElement(titleDiv);
+			this.oDomContainer.removeChild(titleDiv);
+		}
+		if (! close) {
+			YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
+		}
+	}
+};
+
+/**
+* Default handler for the "close" property
+* @method configClose
+*/
+YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
+	var close = args[0];
+	var title = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.TITLE.key);
+	
+	var DEPR_CLOSE_PATH = "us/my/bn/x_d.gif";
+
+	var linkClose;
+
+	if (close === true) {
+		linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
+		linkClose.href = "#";
+		linkClose.className = "link-close";
+		YAHOO.util.Event.addListener(linkClose, "click", function(e, cal) {cal.hide(); YAHOO.util.Event.preventDefault(e); }, this);
+		
+		if (YAHOO.widget.Calendar.IMG_ROOT !== null) {
+			var imgClose = document.createElement("img");
+			imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + DEPR_CLOSE_PATH;
+			imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
+			linkClose.appendChild(imgClose);
+		} else {
+			linkClose.innerHTML = '<span class="' + YAHOO.widget.CalendarGroup.CSS_2UPCLOSE + ' ' + this.Style.CSS_CLOSE + '"></span>';
+		}
+		
+		this.oDomContainer.appendChild(linkClose);
+		YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
+	} else {
+		linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
+		if (linkClose) {
+			YAHOO.util.Event.purgeElement(linkClose);
+			this.oDomContainer.removeChild(linkClose);
+		}
+		if (! title || title === "") {
+			YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
+		}
+	}
+};
+
+/**
+* Initializes Calendar's built-in CustomEvents
+* @method initEvents
+*/
+YAHOO.widget.Calendar.prototype.initEvents = function() {
+
+	var defEvents = YAHOO.widget.Calendar._EVENT_TYPES;
+
+	/**
+	* Fired before a selection is made
+	* @event beforeSelectEvent
+	*/
+	this.beforeSelectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_SELECT); 
+
+	/**
+	* Fired when a selection is made
+	* @event selectEvent
+	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
+	*/
+	this.selectEvent = new YAHOO.util.CustomEvent(defEvents.SELECT);
+
+	/**
+	* Fired before a selection is made
+	* @event beforeDeselectEvent
+	*/
+	this.beforeDeselectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_DESELECT);
+
+	/**
+	* Fired when a selection is made
+	* @event deselectEvent
+	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
+	*/
+	this.deselectEvent = new YAHOO.util.CustomEvent(defEvents.DESELECT);
+
+	/**
+	* Fired when the Calendar page is changed
+	* @event changePageEvent
+	*/
+	this.changePageEvent = new YAHOO.util.CustomEvent(defEvents.CHANGE_PAGE);
+
+	/**
+	* Fired before the Calendar is rendered
+	* @event beforeRenderEvent
+	*/
+	this.beforeRenderEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_RENDER);
+
+	/**
+	* Fired when the Calendar is rendered
+	* @event renderEvent
+	*/
+	this.renderEvent = new YAHOO.util.CustomEvent(defEvents.RENDER);
+
+	/**
+	* Fired when the Calendar is reset
+	* @event resetEvent
+	*/
+	this.resetEvent = new YAHOO.util.CustomEvent(defEvents.RESET);
+
+	/**
+	* Fired when the Calendar is cleared
+	* @event clearEvent
+	*/
+	this.clearEvent = new YAHOO.util.CustomEvent(defEvents.CLEAR);
+
+	this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
+	this.selectEvent.subscribe(this.onSelect, this, true);
+	this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
+	this.deselectEvent.subscribe(this.onDeselect, this, true);
+	this.changePageEvent.subscribe(this.onChangePage, this, true);
+	this.renderEvent.subscribe(this.onRender, this, true);
+	this.resetEvent.subscribe(this.onReset, this, true);
+	this.clearEvent.subscribe(this.onClear, this, true);
+};
+
+/**
+* The default event function that is attached to a date link within a calendar cell
+* when the calendar is rendered.
+* @method doSelectCell
+* @param {DOMEvent} e	The event
+* @param {Calendar} cal	A reference to the calendar passed by the Event utility
+*/
+YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
+	var cell,index,d,date;
+
+	var target = YAHOO.util.Event.getTarget(e);
+	var tagName = target.tagName.toLowerCase();
+	var defSelector = false;
+
+	while (tagName != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
+
+		if (!defSelector && tagName == "a" && YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
+			defSelector = true;	
+		}
+
+		target = target.parentNode;
+		tagName = target.tagName.toLowerCase(); 
+		if (tagName == "html") {
+			return;
+		}
+	}
+
+	if (defSelector) {
+		// Stop link href navigation for default renderer
+		YAHOO.util.Event.preventDefault(e);
+	}
+
+	cell = target;
+
+	if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
+		index = cell.id.split("cell")[1];
+		d = cal.cellDates[index];
+		date = new Date(d[0],d[1]-1,d[2]);
+	
+		var link;
+
+		if (cal.Options.MULTI_SELECT) {
+			link = cell.getElementsByTagName("a")[0];
+			if (link) {
+				link.blur();
+			}
+
+			var cellDate = cal.cellDates[index];
+			var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
+
+			if (cellDateIndex > -1) {	
+				cal.deselectCell(index);
+			} else {
+				cal.selectCell(index);
+			}	
+
+		} else {
+			link = cell.getElementsByTagName("a")[0];
+			if (link) {
+				link.blur();
+			}
+			cal.selectCell(index);
+		}
+	}
+};
+
+/**
+* The event that is executed when the user hovers over a cell
+* @method doCellMouseOver
+* @param {DOMEvent} e	The event
+* @param {Calendar} cal	A reference to the calendar passed by the Event utility
+*/
+YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
+	var target;
+	if (e) {
+		target = YAHOO.util.Event.getTarget(e);
+	} else {
+		target = this;
+	}
+
+	while (target.tagName.toLowerCase() != "td") {
+		target = target.parentNode;
+		if (target.tagName.toLowerCase() == "html") {
+			return;
+		}
+	}
+
+	if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
+		YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
+	}
+};
+
+/**
+* The event that is executed when the user moves the mouse out of a cell
+* @method doCellMouseOut
+* @param {DOMEvent} e	The event
+* @param {Calendar} cal	A reference to the calendar passed by the Event utility
+*/
+YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
+	var target;
+	if (e) {
+		target = YAHOO.util.Event.getTarget(e);
+	} else {
+		target = this;
+	}
+
+	while (target.tagName.toLowerCase() != "td") {
+		target = target.parentNode;
+		if (target.tagName.toLowerCase() == "html") {
+			return;
+		}
+	}
+
+	if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
+		YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
+	}
+};
+
+YAHOO.widget.Calendar.prototype.setupConfig = function() {
+
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+
+	/**
+	* The month/year representing the current visible Calendar date (mm/yyyy)
+	* @config pagedate
+	* @type String
+	* @default today's date
+	*/
+	this.cfg.addProperty(defCfg.PAGEDATE.key, { value:defCfg.PAGEDATE.value, handler:this.configPageDate } );
+
+	/**
+	* The date or range of dates representing the current Calendar selection
+	* @config selected
+	* @type String
+	* @default []
+	*/
+	this.cfg.addProperty(defCfg.SELECTED.key, { value:defCfg.SELECTED.value, handler:this.configSelected } );
+
+	/**
+	* The title to display above the Calendar's month header
+	* @config title
+	* @type String
+	* @default ""
+	*/
+	this.cfg.addProperty(defCfg.TITLE.key, { value:defCfg.TITLE.value, handler:this.configTitle } );
+
+	/**
+	* Whether or not a close button should be displayed for this Calendar
+	* @config close
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(defCfg.CLOSE.key, { value:defCfg.CLOSE.value, handler:this.configClose } );
+
+	/**
+	* Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
+	* @config iframe
+	* @type Boolean
+	* @default true
+	*/
+	this.cfg.addProperty(defCfg.IFRAME.key, { value:defCfg.IFRAME.value, handler:this.configIframe, validator:this.cfg.checkBoolean } );
+
+	/**
+	* The minimum selectable date in the current Calendar (mm/dd/yyyy)
+	* @config mindate
+	* @type String
+	* @default null
+	*/
+	this.cfg.addProperty(defCfg.MINDATE.key, { value:defCfg.MINDATE.value, handler:this.configMinDate } );
+
+	/**
+	* The maximum selectable date in the current Calendar (mm/dd/yyyy)
+	* @config maxdate
+	* @type String
+	* @default null
+	*/
+	this.cfg.addProperty(defCfg.MAXDATE.key, { value:defCfg.MAXDATE.value, handler:this.configMaxDate } );
+
+
+	// Options properties
+
+	/**
+	* True if the Calendar should allow multiple selections. False by default.
+	* @config MULTI_SELECT
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(defCfg.MULTI_SELECT.key,	{ value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+
+	/**
+	* The weekday the week begins on. Default is 0 (Sunday).
+	* @config START_WEEKDAY
+	* @type number
+	* @default 0
+	*/
+	this.cfg.addProperty(defCfg.START_WEEKDAY.key,	{ value:defCfg.START_WEEKDAY.value, handler:this.configOptions, validator:this.cfg.checkNumber  } );
+
+	/**
+	* True if the Calendar should show weekday labels. True by default.
+	* @config SHOW_WEEKDAYS
+	* @type Boolean
+	* @default true
+	*/
+	this.cfg.addProperty(defCfg.SHOW_WEEKDAYS.key,	{ value:defCfg.SHOW_WEEKDAYS.value, handler:this.configOptions, validator:this.cfg.checkBoolean  } );
+
+	/**
+	* True if the Calendar should show week row headers. False by default.
+	* @config SHOW_WEEK_HEADER
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(defCfg.SHOW_WEEK_HEADER.key, { value:defCfg.SHOW_WEEK_HEADER.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+
+	/**
+	* True if the Calendar should show week row footers. False by default.
+	* @config SHOW_WEEK_FOOTER
+	* @type Boolean
+	* @default false
+	*/	
+	this.cfg.addProperty(defCfg.SHOW_WEEK_FOOTER.key,{ value:defCfg.SHOW_WEEK_FOOTER.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+
+	/**
+	* True if the Calendar should suppress weeks that are not a part of the current month. False by default.
+	* @config HIDE_BLANK_WEEKS
+	* @type Boolean
+	* @default false
+	*/	
+	this.cfg.addProperty(defCfg.HIDE_BLANK_WEEKS.key, { value:defCfg.HIDE_BLANK_WEEKS.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+	
+	/**
+	* The image that should be used for the left navigation arrow.
+	* @config NAV_ARROW_LEFT
+	* @type String
+	* @deprecated	You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"  
+	* @default null
+	*/	
+	this.cfg.addProperty(defCfg.NAV_ARROW_LEFT.key,	{ value:defCfg.NAV_ARROW_LEFT.value, handler:this.configOptions } );
+
+	/**
+	* The image that should be used for the right navigation arrow.
+	* @config NAV_ARROW_RIGHT
+	* @type String
+	* @deprecated	You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
+	* @default null
+	*/	
+	this.cfg.addProperty(defCfg.NAV_ARROW_RIGHT.key, { value:defCfg.NAV_ARROW_RIGHT.value, handler:this.configOptions } );
+
+	// Locale properties
+
+	/**
+	* The short month labels for the current locale.
+	* @config MONTHS_SHORT
+	* @type String[]
+	* @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+	*/
+	this.cfg.addProperty(defCfg.MONTHS_SHORT.key,	{ value:defCfg.MONTHS_SHORT.value, handler:this.configLocale } );
+	
+	/**
+	* The long month labels for the current locale.
+	* @config MONTHS_LONG
+	* @type String[]
+	* @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+	*/	
+	this.cfg.addProperty(defCfg.MONTHS_LONG.key,		{ value:defCfg.MONTHS_LONG.value, handler:this.configLocale } );
+	
+	/**
+	* The 1-character weekday labels for the current locale.
+	* @config WEEKDAYS_1CHAR
+	* @type String[]
+	* @default ["S", "M", "T", "W", "T", "F", "S"]
+	*/	
+	this.cfg.addProperty(defCfg.WEEKDAYS_1CHAR.key,	{ value:defCfg.WEEKDAYS_1CHAR.value, handler:this.configLocale } );
+	
+	/**
+	* The short weekday labels for the current locale.
+	* @config WEEKDAYS_SHORT
+	* @type String[]
+	* @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
+	*/	
+	this.cfg.addProperty(defCfg.WEEKDAYS_SHORT.key,	{ value:defCfg.WEEKDAYS_SHORT.value, handler:this.configLocale } );
+	
+	/**
+	* The medium weekday labels for the current locale.
+	* @config WEEKDAYS_MEDIUM
+	* @type String[]
+	* @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+	*/	
+	this.cfg.addProperty(defCfg.WEEKDAYS_MEDIUM.key,	{ value:defCfg.WEEKDAYS_MEDIUM.value, handler:this.configLocale } );
+	
+	/**
+	* The long weekday labels for the current locale.
+	* @config WEEKDAYS_LONG
+	* @type String[]
+	* @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+	*/	
+	this.cfg.addProperty(defCfg.WEEKDAYS_LONG.key,	{ value:defCfg.WEEKDAYS_LONG.value, handler:this.configLocale } );
+
+	/**
+	* Refreshes the locale values used to build the Calendar.
+	* @method refreshLocale
+	* @private
+	*/
+	var refreshLocale = function() {
+		this.cfg.refireEvent(defCfg.LOCALE_MONTHS.key);
+		this.cfg.refireEvent(defCfg.LOCALE_WEEKDAYS.key);
+	};
+
+	this.cfg.subscribeToConfigEvent(defCfg.START_WEEKDAY.key, refreshLocale, this, true);
+	this.cfg.subscribeToConfigEvent(defCfg.MONTHS_SHORT.key, refreshLocale, this, true);
+	this.cfg.subscribeToConfigEvent(defCfg.MONTHS_LONG.key, refreshLocale, this, true);
+	this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_1CHAR.key, refreshLocale, this, true);
+	this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_SHORT.key, refreshLocale, this, true);
+	this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_MEDIUM.key, refreshLocale, this, true);
+	this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_LONG.key, refreshLocale, this, true);
+	
+	/**
+	* The setting that determines which length of month labels should be used. Possible values are "short" and "long".
+	* @config LOCALE_MONTHS
+	* @type String
+	* @default "long"
+	*/	
+	this.cfg.addProperty(defCfg.LOCALE_MONTHS.key,	{ value:defCfg.LOCALE_MONTHS.value, handler:this.configLocaleValues } );
+	
+	/**
+	* The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
+	* @config LOCALE_WEEKDAYS
+	* @type String
+	* @default "short"
+	*/	
+	this.cfg.addProperty(defCfg.LOCALE_WEEKDAYS.key,	{ value:defCfg.LOCALE_WEEKDAYS.value, handler:this.configLocaleValues } );
+
+	/**
+	* The value used to delimit individual dates in a date string passed to various Calendar functions.
+	* @config DATE_DELIMITER
+	* @type String
+	* @default ","
+	*/	
+	this.cfg.addProperty(defCfg.DATE_DELIMITER.key,		{ value:defCfg.DATE_DELIMITER.value, handler:this.configLocale } );
+
+	/**
+	* The value used to delimit date fields in a date string passed to various Calendar functions.
+	* @config DATE_FIELD_DELIMITER
+	* @type String
+	* @default "/"
+	*/	
+	this.cfg.addProperty(defCfg.DATE_FIELD_DELIMITER.key, { value:defCfg.DATE_FIELD_DELIMITER.value, handler:this.configLocale } );
+
+	/**
+	* The value used to delimit date ranges in a date string passed to various Calendar functions.
+	* @config DATE_RANGE_DELIMITER
+	* @type String
+	* @default "-"
+	*/
+	this.cfg.addProperty(defCfg.DATE_RANGE_DELIMITER.key, { value:defCfg.DATE_RANGE_DELIMITER.value, handler:this.configLocale } );
+
+	/**
+	* The position of the month in a month/year date string
+	* @config MY_MONTH_POSITION
+	* @type Number
+	* @default 1
+	*/
+	this.cfg.addProperty(defCfg.MY_MONTH_POSITION.key,	{ value:defCfg.MY_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+
+	/**
+	* The position of the year in a month/year date string
+	* @config MY_YEAR_POSITION
+	* @type Number
+	* @default 2
+	*/
+	this.cfg.addProperty(defCfg.MY_YEAR_POSITION.key,	{ value:defCfg.MY_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+
+	/**
+	* The position of the month in a month/day date string
+	* @config MD_MONTH_POSITION
+	* @type Number
+	* @default 1
+	*/
+	this.cfg.addProperty(defCfg.MD_MONTH_POSITION.key,	{ value:defCfg.MD_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+
+	/**
+	* The position of the day in a month/year date string
+	* @config MD_DAY_POSITION
+	* @type Number
+	* @default 2
+	*/
+	this.cfg.addProperty(defCfg.MD_DAY_POSITION.key,		{ value:defCfg.MD_DAY_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+
+	/**
+	* The position of the month in a month/day/year date string
+	* @config MDY_MONTH_POSITION
+	* @type Number
+	* @default 1
+	*/
+	this.cfg.addProperty(defCfg.MDY_MONTH_POSITION.key,	{ value:defCfg.MDY_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+
+	/**
+	* The position of the day in a month/day/year date string
+	* @config MDY_DAY_POSITION
+	* @type Number
+	* @default 2
+	*/
+	this.cfg.addProperty(defCfg.MDY_DAY_POSITION.key,	{ value:defCfg.MDY_DAY_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+
+	/**
+	* The position of the year in a month/day/year date string
+	* @config MDY_YEAR_POSITION
+	* @type Number
+	* @default 3
+	*/
+	this.cfg.addProperty(defCfg.MDY_YEAR_POSITION.key,	{ value:defCfg.MDY_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+};
+
+/**
+* The default handler for the "pagedate" property
+* @method configPageDate
+*/
+YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
+	this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key, this._parsePageDate(args[0]), true);
+};
+
+/**
+* The default handler for the "mindate" property
+* @method configMinDate
+*/
+YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
+	var val = args[0];
+	if (YAHOO.lang.isString(val)) {
+		val = this._parseDate(val);
+		this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MINDATE.key, new Date(val[0],(val[1]-1),val[2]));
+	}
+};
+
+/**
+* The default handler for the "maxdate" property
+* @method configMaxDate
+*/
+YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
+	var val = args[0];
+	if (YAHOO.lang.isString(val)) {
+		val = this._parseDate(val);
+		this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MAXDATE.key, new Date(val[0],(val[1]-1),val[2]));
+	}
+};
+
+/**
+* The default handler for the "selected" property
+* @method configSelected
+*/
+YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
+	var selected = args[0];
+	var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+	
+	if (selected) {
+		if (YAHOO.lang.isString(selected)) {
+			this.cfg.setProperty(cfgSelected, this._parseDates(selected), true);
+		} 
+	}
+	if (! this._selectedDates) {
+		this._selectedDates = this.cfg.getProperty(cfgSelected);
+	}
+};
+
+/**
+* The default handler for all configuration options properties
+* @method configOptions
+*/
+YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
+	this.Options[type.toUpperCase()] = args[0];
+};
+
+/**
+* The default handler for all configuration locale properties
+* @method configLocale
+*/
+YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+	this.Locale[type.toUpperCase()] = args[0];
+
+	this.cfg.refireEvent(defCfg.LOCALE_MONTHS.key);
+	this.cfg.refireEvent(defCfg.LOCALE_WEEKDAYS.key);
+};
+
+/**
+* The default handler for all configuration locale field length properties
+* @method configLocaleValues
+*/
+YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG; 
+
+	type = type.toLowerCase();
+	var val = args[0];
+
+	switch (type) {
+		case defCfg.LOCALE_MONTHS.key:
+			switch (val) {
+				case YAHOO.widget.Calendar.SHORT:
+					this.Locale.LOCALE_MONTHS = this.cfg.getProperty(defCfg.MONTHS_SHORT.key).concat();
+					break;
+				case YAHOO.widget.Calendar.LONG:
+					this.Locale.LOCALE_MONTHS = this.cfg.getProperty(defCfg.MONTHS_LONG.key).concat();
+					break;
+			}
+			break;
+		case defCfg.LOCALE_WEEKDAYS.key:
+			switch (val) {
+				case YAHOO.widget.Calendar.ONE_CHAR:
+					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_1CHAR.key).concat();
+					break;
+				case YAHOO.widget.Calendar.SHORT:
+					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_SHORT.key).concat();
+					break;
+				case YAHOO.widget.Calendar.MEDIUM:
+					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_MEDIUM.key).concat();
+					break;
+				case YAHOO.widget.Calendar.LONG:
+					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_LONG.key).concat();
+					break;
+			}
+			
+			var START_WEEKDAY = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
+
+			if (START_WEEKDAY > 0) {
+				for (var w=0;w<START_WEEKDAY;++w) {
+					this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());
+				}
+			}
+			break;
+	}
+};
+
+/**
+* Defines the style constants for the Calendar
+* @method initStyles
+*/
+YAHOO.widget.Calendar.prototype.initStyles = function() {
+
+	var defStyle = YAHOO.widget.Calendar._STYLES;
+
+	this.Style = {
+		/**
+		* @property Style.CSS_ROW_HEADER
+		*/
+		CSS_ROW_HEADER: defStyle.CSS_ROW_HEADER,
+		/**
+		* @property Style.CSS_ROW_FOOTER
+		*/
+		CSS_ROW_FOOTER: defStyle.CSS_ROW_FOOTER,
+		/**
+		* @property Style.CSS_CELL
+		*/
+		CSS_CELL : defStyle.CSS_CELL,
+		/**
+		* @property Style.CSS_CELL_SELECTOR
+		*/
+		CSS_CELL_SELECTOR : defStyle.CSS_CELL_SELECTOR,
+		/**
+		* @property Style.CSS_CELL_SELECTED
+		*/
+		CSS_CELL_SELECTED : defStyle.CSS_CELL_SELECTED,
+		/**
+		* @property Style.CSS_CELL_SELECTABLE
+		*/
+		CSS_CELL_SELECTABLE : defStyle.CSS_CELL_SELECTABLE,
+		/**
+		* @property Style.CSS_CELL_RESTRICTED
+		*/
+		CSS_CELL_RESTRICTED : defStyle.CSS_CELL_RESTRICTED,
+		/**
+		* @property Style.CSS_CELL_TODAY
+		*/
+		CSS_CELL_TODAY : defStyle.CSS_CELL_TODAY,
+		/**
+		* @property Style.CSS_CELL_OOM
+		*/
+		CSS_CELL_OOM : defStyle.CSS_CELL_OOM,
+		/**
+		* @property Style.CSS_CELL_OOB
+		*/
+		CSS_CELL_OOB : defStyle.CSS_CELL_OOB,
+		/**
+		* @property Style.CSS_HEADER
+		*/
+		CSS_HEADER : defStyle.CSS_HEADER,
+		/**
+		* @property Style.CSS_HEADER_TEXT
+		*/
+		CSS_HEADER_TEXT : defStyle.CSS_HEADER_TEXT,
+		/**
+		* @property Style.CSS_BODY
+		*/
+		CSS_BODY : defStyle.CSS_BODY,
+		/**
+		* @property Style.CSS_WEEKDAY_CELL
+		*/
+		CSS_WEEKDAY_CELL : defStyle.CSS_WEEKDAY_CELL,
+		/**
+		* @property Style.CSS_WEEKDAY_ROW
+		*/
+		CSS_WEEKDAY_ROW : defStyle.CSS_WEEKDAY_ROW,
+		/**
+		* @property Style.CSS_FOOTER
+		*/
+		CSS_FOOTER : defStyle.CSS_FOOTER,
+		/**
+		* @property Style.CSS_CALENDAR
+		*/
+		CSS_CALENDAR : defStyle.CSS_CALENDAR,
+		/**
+		* @property Style.CSS_SINGLE
+		*/
+		CSS_SINGLE : defStyle.CSS_SINGLE,
+		/**
+		* @property Style.CSS_CONTAINER
+		*/
+		CSS_CONTAINER : defStyle.CSS_CONTAINER,
+		/**
+		* @property Style.CSS_NAV_LEFT
+		*/
+		CSS_NAV_LEFT : defStyle.CSS_NAV_LEFT,
+		/**
+		* @property Style.CSS_NAV_RIGHT
+		*/
+		CSS_NAV_RIGHT : defStyle.CSS_NAV_RIGHT,
+		/**
+		* @property Style.CSS_CLOSE
+		*/
+		CSS_CLOSE : defStyle.CSS_CLOSE,
+		/**
+		* @property Style.CSS_CELL_TOP
+		*/
+		CSS_CELL_TOP : defStyle.CSS_CELL_TOP,
+		/**
+		* @property Style.CSS_CELL_LEFT
+		*/
+		CSS_CELL_LEFT : defStyle.CSS_CELL_LEFT,
+		/**
+		* @property Style.CSS_CELL_RIGHT
+		*/
+		CSS_CELL_RIGHT : defStyle.CSS_CELL_RIGHT,
+		/**
+		* @property Style.CSS_CELL_BOTTOM
+		*/
+		CSS_CELL_BOTTOM : defStyle.CSS_CELL_BOTTOM,
+		/**
+		* @property Style.CSS_CELL_HOVER
+		*/
+		CSS_CELL_HOVER : defStyle.CSS_CELL_HOVER,
+		/**
+		* @property Style.CSS_CELL_HIGHLIGHT1
+		*/
+		CSS_CELL_HIGHLIGHT1 : defStyle.CSS_CELL_HIGHLIGHT1,
+		/**
+		* @property Style.CSS_CELL_HIGHLIGHT2
+		*/
+		CSS_CELL_HIGHLIGHT2 : defStyle.CSS_CELL_HIGHLIGHT2,
+		/**
+		* @property Style.CSS_CELL_HIGHLIGHT3
+		*/
+		CSS_CELL_HIGHLIGHT3 : defStyle.CSS_CELL_HIGHLIGHT3,
+		/**
+		* @property Style.CSS_CELL_HIGHLIGHT4
+		*/
+		CSS_CELL_HIGHLIGHT4 : defStyle.CSS_CELL_HIGHLIGHT4
+	};
+};
+
+/**
+* Builds the date label that will be displayed in the calendar header or
+* footer, depending on configuration.
+* @method buildMonthLabel
+* @return	{String}	The formatted calendar month label
+*/
+YAHOO.widget.Calendar.prototype.buildMonthLabel = function() {
+	var pageDate = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key);
+	return this.Locale.LOCALE_MONTHS[pageDate.getMonth()] + " " + pageDate.getFullYear();
+};
+
+/**
+* Builds the date digit that will be displayed in calendar cells
+* @method buildDayLabel
+* @param {Date}	workingDate	The current working date
+* @return	{String}	The formatted day label
+*/
+YAHOO.widget.Calendar.prototype.buildDayLabel = function(workingDate) {
+	return workingDate.getDate();
+};
+
+/**
+* Renders the calendar header.
+* @method renderHeader
+* @param {Array}	html	The current working HTML array
+* @return {Array} The current working HTML array
+*/
+YAHOO.widget.Calendar.prototype.renderHeader = function(html) {
+	var colSpan = 7;
+	
+	var DEPR_NAV_LEFT = "us/tr/callt.gif";
+	var DEPR_NAV_RIGHT = "us/tr/calrt.gif";	
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+	
+	if (this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key)) {
+		colSpan += 1;
+	}
+
+	if (this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key)) {
+		colSpan += 1;
+	}
+
+	html[html.length] = "<thead>";
+	html[html.length] =		"<tr>";
+	html[html.length] =			'<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
+	html[html.length] =				'<div class="' + this.Style.CSS_HEADER + '">';
+
+	var renderLeft, renderRight = false;
+
+	if (this.parent) {
+		if (this.index === 0) {
+			renderLeft = true;
+		}
+		if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
+			renderRight = true;
+		}
+	} else {
+		renderLeft = true;
+		renderRight = true;
+	}
+
+	var cal = this.parent || this;
+	
+	if (renderLeft) {
+		var leftArrow = this.cfg.getProperty(defCfg.NAV_ARROW_LEFT.key);
+		// Check for deprecated customization - If someone set IMG_ROOT, but didn't set NAV_ARROW_LEFT, then set NAV_ARROW_LEFT to the old deprecated value
+		if (leftArrow === null && YAHOO.widget.Calendar.IMG_ROOT !== null) {
+			leftArrow = YAHOO.widget.Calendar.IMG_ROOT + DEPR_NAV_LEFT;
+		}
+		var leftStyle = (leftArrow === null) ? "" : ' style="background-image:url(' + leftArrow + ')"';
+		html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '"' + leftStyle + ' >&#160;</a>';
+	}
+	
+	html[html.length] = this.buildMonthLabel();
+	
+	if (renderRight) {
+		var rightArrow = this.cfg.getProperty(defCfg.NAV_ARROW_RIGHT.key);
+		if (rightArrow === null && YAHOO.widget.Calendar.IMG_ROOT !== null) {
+			rightArrow = YAHOO.widget.Calendar.IMG_ROOT + DEPR_NAV_RIGHT;
+		}
+		var rightStyle = (rightArrow === null) ? "" : ' style="background-image:url(' + rightArrow + ')"';
+		html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '"' + rightStyle + ' >&#160;</a>';
+	}
+
+	html[html.length] =	'</div>\n</th>\n</tr>';
+
+	if (this.cfg.getProperty(defCfg.SHOW_WEEKDAYS.key)) {
+		html = this.buildWeekdays(html);
+	}
+	
+	html[html.length] = '</thead>';
+
+	return html;
+};
+
+/**
+* Renders the Calendar's weekday headers.
+* @method buildWeekdays
+* @param {Array}	html	The current working HTML array
+* @return {Array} The current working HTML array
+*/
+YAHOO.widget.Calendar.prototype.buildWeekdays = function(html) {
+
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+
+	html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';
+
+	if (this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key)) {
+		html[html.length] = '<th>&#160;</th>';
+	}
+
+	for(var i=0;i<this.Locale.LOCALE_WEEKDAYS.length;++i) {
+		html[html.length] = '<th class="calweekdaycell">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
+	}
+
+	if (this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key)) {
+		html[html.length] = '<th>&#160;</th>';
+	}
+
+	html[html.length] = '</tr>';
+
+	return html;
+};
+
+/**
+* Renders the calendar body.
+* @method renderBody
+* @param {Date}	workingDate	The current working Date being used for the render process
+* @param {Array}	html	The current working HTML array
+* @return {Array} The current working HTML array
+*/
+YAHOO.widget.Calendar.prototype.renderBody = function(workingDate, html) {
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+
+	var startDay = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
+
+	this.preMonthDays = workingDate.getDay();
+	if (startDay > 0) {
+		this.preMonthDays -= startDay;
+	}
+	if (this.preMonthDays < 0) {
+		this.preMonthDays += 7;
+	}
+	
+	this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
+	this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
+	
+	workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
+
+	var weekNum,weekClass;
+	var weekPrefix = "w";
+	var cellPrefix = "_cell";
+	var workingDayPrefix = "wd";
+	var dayPrefix = "d";
+	
+	var cellRenderers;
+	var renderer;
+	
+	var todayYear = this.today.getFullYear();
+	var todayMonth = this.today.getMonth();
+	var todayDate = this.today.getDate();
+	
+	var useDate = this.cfg.getProperty(defCfg.PAGEDATE.key);
+	var hideBlankWeeks = this.cfg.getProperty(defCfg.HIDE_BLANK_WEEKS.key);
+	var showWeekFooter = this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key);
+	var showWeekHeader = this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key);
+	var mindate = this.cfg.getProperty(defCfg.MINDATE.key);
+	var maxdate = this.cfg.getProperty(defCfg.MAXDATE.key);
+
+	if (mindate) {
+		mindate = YAHOO.widget.DateMath.clearTime(mindate);
+	}
+	if (maxdate) {
+		maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
+	}
+	
+	html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + ' ' + this.Style.CSS_BODY + '">';
+	
+	var i = 0;
+
+	var tempDiv = document.createElement("div");
+	var cell = document.createElement("td");
+	tempDiv.appendChild(cell);
+
+	var jan1 = new Date(useDate.getFullYear(),0,1);
+
+	var cal = this.parent || this;
+
+	for (var r=0;r<6;r++) {
+
+		weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);
+		weekClass = weekPrefix + weekNum;
+
+		// Local OOM check for performance, since we already have pagedate
+		if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
+			break;
+		} else {
+
+			html[html.length] = '<tr class="' + weekClass + '">';
+			
+			if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
+			
+			for (var d=0;d<7;d++){ // Render actual days
+
+				cellRenderers = [];
+				renderer = null;
+
+				this.clearElement(cell);
+				cell.className = this.Style.CSS_CELL;
+				cell.id = this.id + cellPrefix + i;
+
+				if (workingDate.getDate()		== todayDate && 
+					workingDate.getMonth()		== todayMonth &&
+					workingDate.getFullYear()	== todayYear) {
+					cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
+				}
+				
+				var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
+				this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
+				
+				// Local OOM check for performance, since we already have pagedate
+				if (workingDate.getMonth() != useDate.getMonth()) {
+					cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
+				} else {
+					YAHOO.util.Dom.addClass(cell, workingDayPrefix + workingDate.getDay());
+					YAHOO.util.Dom.addClass(cell, dayPrefix + workingDate.getDate());
+				
+					for (var s=0;s<this.renderStack.length;++s) {
+
+						var rArray = this.renderStack[s];
+						var type = rArray[0];
+						
+						var month;
+						var day;
+						var year;
+						
+						switch (type) {
+							case YAHOO.widget.Calendar.DATE:
+								month = rArray[1][1];
+								day = rArray[1][2];
+								year = rArray[1][0];
+
+								if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
+									renderer = rArray[2];
+									this.renderStack.splice(s,1);
+								}
+								break;
+							case YAHOO.widget.Calendar.MONTH_DAY:
+								month = rArray[1][0];
+								day = rArray[1][1];
+								
+								if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
+									renderer = rArray[2];
+									this.renderStack.splice(s,1);
+								}
+								break;
+							case YAHOO.widget.Calendar.RANGE:
+								var date1 = rArray[1][0];
+								var date2 = rArray[1][1];
+
+								var d1month = date1[1];
+								var d1day = date1[2];
+								var d1year = date1[0];
+								
+								var d1 = new Date(d1year, d1month-1, d1day);
+
+								var d2month = date2[1];
+								var d2day = date2[2];
+								var d2year = date2[0];
+
+								var d2 = new Date(d2year, d2month-1, d2day);
+
+								if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
+									renderer = rArray[2];
+
+									if (workingDate.getTime()==d2.getTime()) { 
+										this.renderStack.splice(s,1);
+									}
+								}
+								break;
+							case YAHOO.widget.Calendar.WEEKDAY:
+								
+								var weekday = rArray[1][0];
+								if (workingDate.getDay()+1 == weekday) {
+									renderer = rArray[2];
+								}
+								break;
+							case YAHOO.widget.Calendar.MONTH:
+								
+								month = rArray[1][0];
+								if (workingDate.getMonth()+1 == month) {
+									renderer = rArray[2];
+								}
+								break;
+						}
+						
+						if (renderer) {
+							cellRenderers[cellRenderers.length]=renderer;
+						}
+					}
+
+				}
+
+				if (this._indexOfSelectedFieldArray(workingArray) > -1) {
+					cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected; 
+				}
+
+				if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
+					(maxdate && (workingDate.getTime() > maxdate.getTime()))
+				) {
+					cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
+				} else {
+					cellRenderers[cellRenderers.length]=cal.styleCellDefault;
+					cellRenderers[cellRenderers.length]=cal.renderCellDefault;	
+				}
+				
+				for (var x=0; x < cellRenderers.length; ++x) {
+					if (cellRenderers[x].call(cal, workingDate, cell) == YAHOO.widget.Calendar.STOP_RENDER) {
+						break;
+					}
+				}
+
+				workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
+
+				if (i >= 0 && i <= 6) {
+					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
+				}
+				if ((i % 7) === 0) {
+					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
+				}
+				if (((i+1) % 7) === 0) {
+					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
+				}
+				
+				var postDays = this.postMonthDays; 
+				if (hideBlankWeeks && postDays >= 7) {
+					var blankWeeks = Math.floor(postDays/7);
+					for (var p=0;p<blankWeeks;++p) {
+						postDays -= 7;
+					}
+				}
+				
+				if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
+					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
+				}
+
+				html[html.length] = tempDiv.innerHTML;
+				i++;
+			}
+
+			if (showWeekFooter) { html = this.renderRowFooter(weekNum, html); }
+
+			html[html.length] = '</tr>';
+		}
+	}
+
+	html[html.length] = '</tbody>';
+
+	return html;
+};
+
+/**
+* Renders the calendar footer. In the default implementation, there is
+* no footer.
+* @method renderFooter
+* @param {Array}	html	The current working HTML array
+* @return {Array} The current working HTML array
+*/
+YAHOO.widget.Calendar.prototype.renderFooter = function(html) { return html; };
+
+/**
+* Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
+* when the method is called: renderHeader, renderBody, renderFooter.
+* Refer to the documentation for those methods for information on 
+* individual render tasks.
+* @method render
+*/
+YAHOO.widget.Calendar.prototype.render = function() {
+	this.beforeRenderEvent.fire();
+
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+
+	// Find starting day of the current month
+	var workingDate = YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty(defCfg.PAGEDATE.key));
+
+	this.resetRenderers();
+	this.cellDates.length = 0;
+
+	YAHOO.util.Event.purgeElement(this.oDomContainer, true);
+
+	var html = [];
+
+	html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + workingDate.getFullYear() + '" id="' + this.id + '">';
+	html = this.renderHeader(html);
+	html = this.renderBody(workingDate, html);
+	html = this.renderFooter(html);
+	html[html.length] = '</table>';
+
+	this.oDomContainer.innerHTML = html.join("\n");
+
+	this.applyListeners();
+	this.cells = this.oDomContainer.getElementsByTagName("td");
+
+	this.cfg.refireEvent(defCfg.TITLE.key);
+	this.cfg.refireEvent(defCfg.CLOSE.key);
+	this.cfg.refireEvent(defCfg.IFRAME.key);
+
+	this.renderEvent.fire();
+};
+
+/**
+* Applies the Calendar's DOM listeners to applicable elements.
+* @method applyListeners
+*/
+YAHOO.widget.Calendar.prototype.applyListeners = function() {
+	
+	var root = this.oDomContainer;
+	var cal = this.parent || this;
+	
+	var anchor = "a";
+	var mousedown = "mousedown";
+
+	var linkLeft = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, anchor, root);
+	var linkRight = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, anchor, root);
+
+	if (linkLeft && linkLeft.length > 0) {
+		this.linkLeft = linkLeft[0];
+		YAHOO.util.Event.addListener(this.linkLeft, mousedown, cal.previousMonth, cal, true);
+	}
+
+	if (linkRight && linkRight.length > 0) {
+		this.linkRight = linkRight[0];
+		YAHOO.util.Event.addListener(this.linkRight, mousedown, cal.nextMonth, cal, true);
+	}
+
+	if (this.domEventMap) {
+		var el,elements;
+		for (var cls in this.domEventMap) {	
+			if (YAHOO.lang.hasOwnProperty(this.domEventMap, cls)) {
+				var items = this.domEventMap[cls];
+
+				if (! (items instanceof Array)) {
+					items = [items];
+				}
+
+				for (var i=0;i<items.length;i++)	{
+					var item = items[i];
+					elements = YAHOO.util.Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);
+
+					for (var c=0;c<elements.length;c++) {
+						el = elements[c];
+						 YAHOO.util.Event.addListener(el, item.event, item.handler, item.scope, item.correct );
+					}
+				}
+			}
+		}
+	}
+
+	YAHOO.util.Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
+	YAHOO.util.Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
+	YAHOO.util.Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
+};
+
+/**
+* Retrieves the Date object for the specified Calendar cell
+* @method getDateByCellId
+* @param {String}	id	The id of the cell
+* @return {Date} The Date object for the specified Calendar cell
+*/
+YAHOO.widget.Calendar.prototype.getDateByCellId = function(id) {
+	var date = this.getDateFieldsByCellId(id);
+	return new Date(date[0],date[1]-1,date[2]);
+};
+
+/**
+* Retrieves the Date object for the specified Calendar cell
+* @method getDateFieldsByCellId
+* @param {String}	id	The id of the cell
+* @return {Array}	The array of Date fields for the specified Calendar cell
+*/
+YAHOO.widget.Calendar.prototype.getDateFieldsByCellId = function(id) {
+	id = id.toLowerCase().split("_cell")[1];
+	id = parseInt(id, 10);
+	return this.cellDates[id];
+};
+
+// BEGIN BUILT-IN TABLE CELL RENDERERS
+
+/**
+* Renders a cell that falls before the minimum date or after the maximum date.
+* widget class.
+* @method renderOutOfBoundsDate
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+*			should not be terminated
+*/
+YAHOO.widget.Calendar.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
+	cell.innerHTML = workingDate.getDate();
+	return YAHOO.widget.Calendar.STOP_RENDER;
+};
+
+/**
+* Renders the row header for a week.
+* @method renderRowHeader
+* @param {Number}	weekNum	The week number of the current row
+* @param {Array}	cell	The current working HTML array
+*/
+YAHOO.widget.Calendar.prototype.renderRowHeader = function(weekNum, html) {
+	html[html.length] = '<th class="calrowhead">' + weekNum + '</th>';
+	return html;
+};
+
+/**
+* Renders the row footer for a week.
+* @method renderRowFooter
+* @param {Number}	weekNum	The week number of the current row
+* @param {Array}	cell	The current working HTML array
+*/
+YAHOO.widget.Calendar.prototype.renderRowFooter = function(weekNum, html) {
+	html[html.length] = '<th class="calrowfoot">' + weekNum + '</th>';
+	return html;
+};
+
+/**
+* Renders a single standard calendar cell in the calendar widget table.
+* All logic for determining how a standard default cell will be rendered is 
+* encapsulated in this method, and must be accounted for when extending the
+* widget class.
+* @method renderCellDefault
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell) {
+	cell.innerHTML = '<a href="#" class="' + this.Style.CSS_CELL_SELECTOR + '">' + this.buildDayLabel(workingDate) + "</a>";
+};
+
+/**
+* Styles a selectable cell.
+* @method styleCellDefault
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.styleCellDefault = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
+};
+
+
+/**
+* Renders a single standard calendar cell using the CSS hightlight1 style
+* @method renderCellStyleHighlight1
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
+};
+
+/**
+* Renders a single standard calendar cell using the CSS hightlight2 style
+* @method renderCellStyleHighlight2
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
+};
+
+/**
+* Renders a single standard calendar cell using the CSS hightlight3 style
+* @method renderCellStyleHighlight3
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
+};
+
+/**
+* Renders a single standard calendar cell using the CSS hightlight4 style
+* @method renderCellStyleHighlight4
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
+};
+
+/**
+* Applies the default style used for rendering today's date to the current calendar cell
+* @method renderCellStyleToday
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+*/
+YAHOO.widget.Calendar.prototype.renderCellStyleToday = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
+};
+
+/**
+* Applies the default style used for rendering selected dates to the current calendar cell
+* @method renderCellStyleSelected
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+*			should not be terminated
+*/
+YAHOO.widget.Calendar.prototype.renderCellStyleSelected = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
+};
+
+/**
+* Applies the default style used for rendering dates that are not a part of the current
+* month (preceding or trailing the cells for the current month)
+* @method renderCellNotThisMonth
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+*			should not be terminated
+*/
+YAHOO.widget.Calendar.prototype.renderCellNotThisMonth = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);
+	cell.innerHTML=workingDate.getDate();
+	return YAHOO.widget.Calendar.STOP_RENDER;
+};
+
+/**
+* Renders the current calendar cell as a non-selectable "black-out" date using the default
+* restricted style.
+* @method renderBodyCellRestricted
+* @param {Date}					workingDate		The current working Date object being used to generate the calendar
+* @param {HTMLTableCellElement}	cell			The current working cell in the calendar
+* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+*			should not be terminated
+*/
+YAHOO.widget.Calendar.prototype.renderBodyCellRestricted = function(workingDate, cell) {
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);
+	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
+	cell.innerHTML=workingDate.getDate();
+	return YAHOO.widget.Calendar.STOP_RENDER;
+};
+
+// END BUILT-IN TABLE CELL RENDERERS
+
+// BEGIN MONTH NAVIGATION METHODS
+
+/**
+* Adds the designated number of months to the current calendar month, and sets the current
+* calendar page date to the new month.
+* @method addMonths
+* @param {Number}	count	The number of months to add to the current calendar
+*/
+YAHOO.widget.Calendar.prototype.addMonths = function(count) {
+	var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
+	this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.add(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.MONTH, count));
+	this.resetRenderers();
+	this.changePageEvent.fire();
+};
+
+/**
+* Subtracts the designated number of months from the current calendar month, and sets the current
+* calendar page date to the new month.
+* @method subtractMonths
+* @param {Number}	count	The number of months to subtract from the current calendar
+*/
+YAHOO.widget.Calendar.prototype.subtractMonths = function(count) {
+	var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
+	this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.subtract(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.MONTH, count));
+	this.resetRenderers();
+	this.changePageEvent.fire();
+};
+
+/**
+* Adds the designated number of years to the current calendar, and sets the current
+* calendar page date to the new month.
+* @method addYears
+* @param {Number}	count	The number of years to add to the current calendar
+*/
+YAHOO.widget.Calendar.prototype.addYears = function(count) {
+	var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
+	this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.add(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.YEAR, count));
+	this.resetRenderers();
+	this.changePageEvent.fire();
+};
+
+/**
+* Subtcats the designated number of years from the current calendar, and sets the current
+* calendar page date to the new month.
+* @method subtractYears
+* @param {Number}	count	The number of years to subtract from the current calendar
+*/
+YAHOO.widget.Calendar.prototype.subtractYears = function(count) {
+	var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
+	this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.subtract(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.YEAR, count));
+	this.resetRenderers();
+	this.changePageEvent.fire();
+};
+
+/**
+* Navigates to the next month page in the calendar widget.
+* @method nextMonth
+*/
+YAHOO.widget.Calendar.prototype.nextMonth = function() {
+	this.addMonths(1);
+};
+
+/**
+* Navigates to the previous month page in the calendar widget.
+* @method previousMonth
+*/
+YAHOO.widget.Calendar.prototype.previousMonth = function() {
+	this.subtractMonths(1);
+};
+
+/**
+* Navigates to the next year in the currently selected month in the calendar widget.
+* @method nextYear
+*/
+YAHOO.widget.Calendar.prototype.nextYear = function() {
+	this.addYears(1);
+};
+
+/**
+* Navigates to the previous year in the currently selected month in the calendar widget.
+* @method previousYear
+*/
+YAHOO.widget.Calendar.prototype.previousYear = function() {
+	this.subtractYears(1);
+};
+
+// END MONTH NAVIGATION METHODS
+
+// BEGIN SELECTION METHODS
+
+/**
+* Resets the calendar widget to the originally selected month and year, and 
+* sets the calendar to the initial selection(s).
+* @method reset
+*/
+YAHOO.widget.Calendar.prototype.reset = function() {
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+	this.cfg.resetProperty(defCfg.SELECTED.key);
+	this.cfg.resetProperty(defCfg.PAGEDATE.key);
+	this.resetEvent.fire();
+};
+
+/**
+* Clears the selected dates in the current calendar widget and sets the calendar
+* to the current month and year.
+* @method clear
+*/
+YAHOO.widget.Calendar.prototype.clear = function() {
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+	this.cfg.setProperty(defCfg.SELECTED.key, []);
+	this.cfg.setProperty(defCfg.PAGEDATE.key, new Date(this.today.getTime()));
+	this.clearEvent.fire();
+};
+
+/**
+* Selects a date or a collection of dates on the current calendar. This method, by default,
+* does not call the render method explicitly. Once selection has completed, render must be 
+* called for the changes to be reflected visually.
+* @method select
+* @param	{String/Date/Date[]}	date	The date string of dates to select in the current calendar. Valid formats are
+*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
+*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
+*								This method can also take a JavaScript Date object or an array of Date objects.
+* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.Calendar.prototype.select = function(date) {
+	this.beforeSelectEvent.fire();
+	
+	var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+
+	var selected = this.cfg.getProperty(cfgSelected);
+	var aToBeSelected = this._toFieldArray(date);
+
+	for (var a=0;a<aToBeSelected.length;++a) {
+		var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
+		if (this._indexOfSelectedFieldArray(toSelect) == -1) { // not already selected?
+			selected[selected.length]=toSelect;
+		}
+	}
+	
+	if (this.parent) {
+		this.parent.cfg.setProperty(cfgSelected, selected);
+	} else {
+		this.cfg.setProperty(cfgSelected, selected);
+	}
+
+	this.selectEvent.fire(aToBeSelected);
+	
+	return this.getSelectedDates();
+};
+
+/**
+* Selects a date on the current calendar by referencing the index of the cell that should be selected.
+* This method is used to easily select a single cell (usually with a mouse click) without having to do
+* a full render. The selected style is applied to the cell directly.
+* @method selectCell
+* @param	{Number}	cellIndex	The index of the cell to select in the current calendar. 
+* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.Calendar.prototype.selectCell = function(cellIndex) {
+	this.beforeSelectEvent.fire();
+	
+	var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+	var selected = this.cfg.getProperty(cfgSelected);
+
+	var cell = this.cells[cellIndex];
+	var cellDate = this.cellDates[cellIndex];
+
+	var dCellDate = this._toDate(cellDate);
+
+	var selectDate = cellDate.concat();
+
+	if (this._indexOfSelectedFieldArray(selectDate) == -1) {
+		selected[selected.length] = selectDate;
+	}
+
+	if (this.parent) {
+		this.parent.cfg.setProperty(cfgSelected, selected);
+	} else {
+		this.cfg.setProperty(cfgSelected, selected);
+	}
+
+	this.renderCellStyleSelected(dCellDate,cell);
+
+	this.selectEvent.fire([selectDate]);
+
+	this.doCellMouseOut.call(cell, null, this);
+
+	return this.getSelectedDates();
+};
+
+/**
+* Deselects a date or a collection of dates on the current calendar. This method, by default,
+* does not call the render method explicitly. Once deselection has completed, render must be 
+* called for the changes to be reflected visually.
+* @method deselect
+* @param	{String/Date/Date[]}	date	The date string of dates to deselect in the current calendar. Valid formats are
+*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
+*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
+*								This method can also take a JavaScript Date object or an array of Date objects.	
+* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.Calendar.prototype.deselect = function(date) {
+	this.beforeDeselectEvent.fire();
+	var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+
+	var selected = this.cfg.getProperty(cfgSelected);
+
+	var aToBeSelected = this._toFieldArray(date);
+
+	for (var a=0;a<aToBeSelected.length;++a) {
+		var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
+		var index = this._indexOfSelectedFieldArray(toSelect);
+	
+		if (index != -1) {	
+			selected.splice(index,1);
+		}
+	}
+
+	if (this.parent) {
+		this.parent.cfg.setProperty(cfgSelected, selected);
+	} else {
+		this.cfg.setProperty(cfgSelected, selected);
+	}
+
+	this.deselectEvent.fire(aToBeSelected);
+	
+	return this.getSelectedDates();
+};
+
+/**
+* Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
+* This method is used to easily deselect a single cell (usually with a mouse click) without having to do
+* a full render. The selected style is removed from the cell directly.
+* @method deselectCell
+* @param	{Number}	cellIndex	The index of the cell to deselect in the current calendar. 
+* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.Calendar.prototype.deselectCell = function(i) {
+	this.beforeDeselectEvent.fire();
+	
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+	
+	var selected = this.cfg.getProperty(defCfg.SELECTED.key);
+
+	var cell = this.cells[i];
+	var cellDate = this.cellDates[i];
+	var cellDateIndex = this._indexOfSelectedFieldArray(cellDate);
+
+	var dCellDate = this._toDate(cellDate);
+
+	var selectDate = cellDate.concat();
+
+	if (cellDateIndex > -1) {
+		if (this.cfg.getProperty(defCfg.PAGEDATE.key).getMonth() == dCellDate.getMonth() &&
+			this.cfg.getProperty(defCfg.PAGEDATE.key).getFullYear() == dCellDate.getFullYear()) {
+			YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
+		}
+
+		selected.splice(cellDateIndex, 1);
+	}
+
+	if (this.parent) {
+		this.parent.cfg.setProperty(defCfg.SELECTED.key, selected);
+	} else {
+		this.cfg.setProperty(defCfg.SELECTED.key, selected);
+	}
+	
+	this.deselectEvent.fire(selectDate);
+	return this.getSelectedDates();
+};
+
+/**
+* Deselects all dates on the current calendar.
+* @method deselectAll
+* @return {Date[]}		Array of JavaScript Date objects representing all individual dates that are currently selected.
+*						Assuming that this function executes properly, the return value should be an empty array.
+*						However, the empty array is returned for the sake of being able to check the selection status
+*						of the calendar.
+*/
+YAHOO.widget.Calendar.prototype.deselectAll = function() {
+	this.beforeDeselectEvent.fire();
+	
+	var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+
+	var selected = this.cfg.getProperty(cfgSelected);
+	var count = selected.length;
+	var sel = selected.concat();
+
+	if (this.parent) {
+		this.parent.cfg.setProperty(cfgSelected, []);
+	} else {
+		this.cfg.setProperty(cfgSelected, []);
+	}
+	
+	if (count > 0) {
+		this.deselectEvent.fire(sel);
+	}
+
+	return this.getSelectedDates();
+};
+
+// END SELECTION METHODS
+
+// BEGIN TYPE CONVERSION METHODS
+
+/**
+* Converts a date (either a JavaScript Date object, or a date string) to the internal data structure
+* used to represent dates: [[yyyy,mm,dd],[yyyy,mm,dd]].
+* @method _toFieldArray
+* @private
+* @param	{String/Date/Date[]}	date	The date string of dates to deselect in the current calendar. Valid formats are
+*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
+*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
+*								This method can also take a JavaScript Date object or an array of Date objects.	
+* @return {Array[](Number[])}	Array of date field arrays
+*/
+YAHOO.widget.Calendar.prototype._toFieldArray = function(date) {
+	var returnDate = [];
+
+	if (date instanceof Date) {
+		returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
+	} else if (YAHOO.lang.isString(date)) {
+		returnDate = this._parseDates(date);
+	} else if (YAHOO.lang.isArray(date)) {
+		for (var i=0;i<date.length;++i) {
+			var d = date[i];
+			returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
+		}
+	}
+	
+	return returnDate;
+};
+
+/**
+* Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
+* @method _toDate
+* @private
+* @param	{Number[]}		dateFieldArray	The date field array to convert to a JavaScript Date.
+* @return	{Date}	JavaScript Date object representing the date field array
+*/
+YAHOO.widget.Calendar.prototype._toDate = function(dateFieldArray) {
+	if (dateFieldArray instanceof Date) {
+		return dateFieldArray;
+	} else {
+		return new Date(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
+	}
+};
+
+// END TYPE CONVERSION METHODS 
+
+// BEGIN UTILITY METHODS
+
+/**
+* Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
+* @method _fieldArraysAreEqual
+* @private
+* @param	{Number[]}	array1	The first date field array to compare
+* @param	{Number[]}	array2	The first date field array to compare
+* @return	{Boolean}	The boolean that represents the equality of the two arrays
+*/
+YAHOO.widget.Calendar.prototype._fieldArraysAreEqual = function(array1, array2) {
+	var match = false;
+
+	if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
+		match=true;	
+	}
+
+	return match;
+};
+
+/**
+* Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
+* @method	_indexOfSelectedFieldArray
+* @private
+* @param	{Number[]}		find	The date field array to search for
+* @return	{Number}			The index of the date field array within the collection of selected dates.
+*								-1 will be returned if the date is not found.
+*/
+YAHOO.widget.Calendar.prototype._indexOfSelectedFieldArray = function(find) {
+	var selected = -1;
+	var seldates = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);
+
+	for (var s=0;s<seldates.length;++s) {
+		var sArray = seldates[s];
+		if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
+			selected = s;
+			break;
+		}
+	}
+
+	return selected;
+};
+
+/**
+* Determines whether a given date is OOM (out of month).
+* @method	isDateOOM
+* @param	{Date}	date	The JavaScript Date object for which to check the OOM status
+* @return	{Boolean}	true if the date is OOM
+*/
+YAHOO.widget.Calendar.prototype.isDateOOM = function(date) {
+	return (date.getMonth() != this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key).getMonth());
+};
+
+/**
+ * Parses a pagedate configuration property value. The value can either be specified as a string of form "mm/yyyy" or a Date object 
+ * and is parsed into a Date object normalized to the first day of the month. If no value is passed in, the month and year from today's date are used to create the Date object 
+ * @method	_parsePageDate
+ * @private
+ * @param {Date|String}	date	Pagedate value which needs to be parsed
+ * @return {Date}	The Date object representing the pagedate
+ */
+YAHOO.widget.Calendar.prototype._parsePageDate = function(date) {
+	var parsedDate;
+	
+	var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+
+	if (date) {
+		if (date instanceof Date) {
+			parsedDate = YAHOO.widget.DateMath.findMonthStart(date);
+		} else {
+			var month, year, aMonthYear;
+			aMonthYear = date.split(this.cfg.getProperty(defCfg.DATE_FIELD_DELIMITER.key));
+			month = parseInt(aMonthYear[this.cfg.getProperty(defCfg.MY_MONTH_POSITION.key)-1], 10)-1;
+			year = parseInt(aMonthYear[this.cfg.getProperty(defCfg.MY_YEAR_POSITION.key)-1], 10);
+			
+			parsedDate = new Date(year, month, 1);
+		}
+	} else {
+		parsedDate = new Date(this.today.getFullYear(), this.today.getMonth(), 1);
+	}
+	return parsedDate;
+};
+
+// END UTILITY METHODS
+
+// BEGIN EVENT HANDLERS
+
+/**
+* Event executed before a date is selected in the calendar widget.
+* @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
+*/
+YAHOO.widget.Calendar.prototype.onBeforeSelect = function() {
+	if (this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MULTI_SELECT.key) === false) {
+		if (this.parent) {
+			this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
+			this.parent.deselectAll();
+		} else {
+			this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
+			this.deselectAll();
+		}
+	}
+};
+
+/**
+* Event executed when a date is selected in the calendar widget.
+* @param	{Array}	selected	An array of date field arrays representing which date or dates were selected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
+* @deprecated Event handlers for this event should be susbcribed to selectEvent.
+*/
+YAHOO.widget.Calendar.prototype.onSelect = function(selected) { };
+
+/**
+* Event executed before a date is deselected in the calendar widget.
+* @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
+*/
+YAHOO.widget.Calendar.prototype.onBeforeDeselect = function() { };
+
+/**
+* Event executed when a date is deselected in the calendar widget.
+* @param	{Array}	selected	An array of date field arrays representing which date or dates were deselected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
+* @deprecated Event handlers for this event should be susbcribed to deselectEvent.
+*/
+YAHOO.widget.Calendar.prototype.onDeselect = function(deselected) { };
+
+/**
+* Event executed when the user navigates to a different calendar page.
+* @deprecated Event handlers for this event should be susbcribed to changePageEvent.
+*/
+YAHOO.widget.Calendar.prototype.onChangePage = function() {
+	this.render();
+};
+
+/**
+* Event executed when the calendar widget is rendered.
+* @deprecated Event handlers for this event should be susbcribed to renderEvent.
+*/
+YAHOO.widget.Calendar.prototype.onRender = function() { };
+
+/**
+* Event executed when the calendar widget is reset to its original state.
+* @deprecated Event handlers for this event should be susbcribed to resetEvemt.
+*/
+YAHOO.widget.Calendar.prototype.onReset = function() { this.render(); };
+
+/**
+* Event executed when the calendar widget is completely cleared to the current month with no selections.
+* @deprecated Event handlers for this event should be susbcribed to clearEvent.
+*/
+YAHOO.widget.Calendar.prototype.onClear = function() { this.render(); };
+
+/**
+* Validates the calendar widget. This method has no default implementation
+* and must be extended by subclassing the widget.
+* @return	Should return true if the widget validates, and false if
+* it doesn't.
+* @type Boolean
+*/
+YAHOO.widget.Calendar.prototype.validate = function() { return true; };
+
+// END EVENT HANDLERS
+
+// BEGIN DATE PARSE METHODS
+
+/**
+* Converts a date string to a date field array
+* @private
+* @param	{String}	sDate			Date string. Valid formats are mm/dd and mm/dd/yyyy.
+* @return				A date field array representing the string passed to the method
+* @type Array[](Number[])
+*/
+YAHOO.widget.Calendar.prototype._parseDate = function(sDate) {
+	var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER);
+	var rArray;
+
+	if (aDate.length == 2) {
+		rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
+		rArray.type = YAHOO.widget.Calendar.MONTH_DAY;
+	} else {
+		rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
+		rArray.type = YAHOO.widget.Calendar.DATE;
+	}
+
+	for (var i=0;i<rArray.length;i++) {
+		rArray[i] = parseInt(rArray[i], 10);
+	}
+
+	return rArray;
+};
+
+/**
+* Converts a multi or single-date string to an array of date field arrays
+* @private
+* @param	{String}	sDates		Date string with one or more comma-delimited dates. Valid formats are mm/dd, mm/dd/yyyy, mm/dd/yyyy-mm/dd/yyyy
+* @return							An array of date field arrays
+* @type Array[](Number[])
+*/
+YAHOO.widget.Calendar.prototype._parseDates = function(sDates) {
+	var aReturn = [];
+
+	var aDates = sDates.split(this.Locale.DATE_DELIMITER);
+	
+	for (var d=0;d<aDates.length;++d) {
+		var sDate = aDates[d];
+
+		if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
+			// This is a range
+			var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER);
+
+			var dateStart = this._parseDate(aRange[0]);
+			var dateEnd = this._parseDate(aRange[1]);
+
+			var fullRange = this._parseRange(dateStart, dateEnd);
+			aReturn = aReturn.concat(fullRange);
+		} else {
+			// This is not a range
+			var aDate = this._parseDate(sDate);
+			aReturn.push(aDate);
+		}
+	}
+	return aReturn;
+};
+
+/**
+* Converts a date range to the full list of included dates
+* @private
+* @param	{Number[]}	startDate	Date field array representing the first date in the range
+* @param	{Number[]}	endDate		Date field array representing the last date in the range
+* @return							An array of date field arrays
+* @type Array[](Number[])
+*/
+YAHOO.widget.Calendar.prototype._parseRange = function(startDate, endDate) {
+	var dStart   = new Date(startDate[0],startDate[1]-1,startDate[2]);
+	var dCurrent = YAHOO.widget.DateMath.add(new Date(startDate[0],startDate[1]-1,startDate[2]),YAHOO.widget.DateMath.DAY,1);
+	var dEnd     = new Date(endDate[0],  endDate[1]-1,  endDate[2]);
+
+	var results = [];
+	results.push(startDate);
+	while (dCurrent.getTime() <= dEnd.getTime()) {
+		results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
+		dCurrent = YAHOO.widget.DateMath.add(dCurrent,YAHOO.widget.DateMath.DAY,1);
+	}
+	return results;
+};
+
+// END DATE PARSE METHODS
+
+// BEGIN RENDERER METHODS
+
+/**
+* Resets the render stack of the current calendar to its original pre-render value.
+*/
+YAHOO.widget.Calendar.prototype.resetRenderers = function() {
+	this.renderStack = this._renderStack.concat();
+};
+
+/**
+* Clears the inner HTML, CSS class and style information from the specified cell.
+* @method clearElement
+* @param	{HTMLTableCellElement}	The cell to clear
+*/ 
+YAHOO.widget.Calendar.prototype.clearElement = function(cell) {
+	cell.innerHTML = "&#160;";
+	cell.className="";
+};
+
+/**
+* Adds a renderer to the render stack. The function reference passed to this method will be executed
+* when a date cell matches the conditions specified in the date string for this renderer.
+* @method addRenderer
+* @param	{String}	sDates		A date string to associate with the specified renderer. Valid formats
+*									include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.Calendar.prototype.addRenderer = function(sDates, fnRender) {
+	var aDates = this._parseDates(sDates);
+	for (var i=0;i<aDates.length;++i) {
+		var aDate = aDates[i];
+	
+		if (aDate.length == 2) { // this is either a range or a month/day combo
+			if (aDate[0] instanceof Array) { // this is a range
+				this._addRenderer(YAHOO.widget.Calendar.RANGE,aDate,fnRender);
+			} else { // this is a month/day combo
+				this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,aDate,fnRender);
+			}
+		} else if (aDate.length == 3) {
+			this._addRenderer(YAHOO.widget.Calendar.DATE,aDate,fnRender);
+		}
+	}
+};
+
+/**
+* The private method used for adding cell renderers to the local render stack.
+* This method is called by other methods that set the renderer type prior to the method call.
+* @method _addRenderer
+* @private
+* @param	{String}	type		The type string that indicates the type of date renderer being added.
+*									Values are YAHOO.widget.Calendar.DATE, YAHOO.widget.Calendar.MONTH_DAY, YAHOO.widget.Calendar.WEEKDAY,
+*									YAHOO.widget.Calendar.RANGE, YAHOO.widget.Calendar.MONTH
+* @param	{Array}		aDates		An array of dates used to construct the renderer. The format varies based
+*									on the renderer type
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.Calendar.prototype._addRenderer = function(type, aDates, fnRender) {
+	var add = [type,aDates,fnRender];
+	this.renderStack.unshift(add);	
+	this._renderStack = this.renderStack.concat();
+};
+
+/**
+* Adds a month to the render stack. The function reference passed to this method will be executed
+* when a date cell matches the month passed to this method.
+* @method addMonthRenderer
+* @param	{Number}	month		The month (1-12) to associate with this renderer
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.Calendar.prototype.addMonthRenderer = function(month, fnRender) {
+	this._addRenderer(YAHOO.widget.Calendar.MONTH,[month],fnRender);
+};
+
+/**
+* Adds a weekday to the render stack. The function reference passed to this method will be executed
+* when a date cell matches the weekday passed to this method.
+* @method addWeekdayRenderer
+* @param	{Number}	weekday		The weekday (0-6) to associate with this renderer
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.Calendar.prototype.addWeekdayRenderer = function(weekday, fnRender) {
+	this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
+};
+
+// END RENDERER METHODS
+
+// BEGIN CSS METHODS
+
+/**
+* Removes all styles from all body cells in the current calendar table.
+* @method clearAllBodyCellStyles
+* @param	{style}		The CSS class name to remove from all calendar body cells
+*/
+YAHOO.widget.Calendar.prototype.clearAllBodyCellStyles = function(style) {
+	for (var c=0;c<this.cells.length;++c) {
+		YAHOO.util.Dom.removeClass(this.cells[c],style);
+	}
+};
+
+// END CSS METHODS
+
+// BEGIN GETTER/SETTER METHODS
+/**
+* Sets the calendar's month explicitly
+* @method setMonth
+* @param {Number}	month		The numeric month, from 0 (January) to 11 (December)
+*/
+YAHOO.widget.Calendar.prototype.setMonth = function(month) {
+	var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
+	var current = this.cfg.getProperty(cfgPageDate);
+	current.setMonth(parseInt(month, 10));
+	this.cfg.setProperty(cfgPageDate, current);
+};
+
+/**
+* Sets the calendar's year explicitly.
+* @method setYear
+* @param {Number}	year		The numeric 4-digit year
+*/
+YAHOO.widget.Calendar.prototype.setYear = function(year) {
+	var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
+	var current = this.cfg.getProperty(cfgPageDate);
+	current.setFullYear(parseInt(year, 10));
+	this.cfg.setProperty(cfgPageDate, current);
+};
+
+/**
+* Gets the list of currently selected dates from the calendar.
+* @method getSelectedDates
+* @return {Date[]} An array of currently selected JavaScript Date objects.
+*/
+YAHOO.widget.Calendar.prototype.getSelectedDates = function() {
+	var returnDates = [];
+	var selected = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);
+
+	for (var d=0;d<selected.length;++d) {
+		var dateArray = selected[d];
+
+		var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
+		returnDates.push(date);
+	}
+
+	returnDates.sort( function(a,b) { return a-b; } );
+	return returnDates;
+};
+
+/// END GETTER/SETTER METHODS ///
+
+/**
+* Hides the Calendar's outer container from view.
+* @method hide
+*/
+YAHOO.widget.Calendar.prototype.hide = function() {
+	this.oDomContainer.style.display = "none";
+};
+
+/**
+* Shows the Calendar's outer container.
+* @method show
+*/
+YAHOO.widget.Calendar.prototype.show = function() {
+	this.oDomContainer.style.display = "block";
+};
+
+/**
+* Returns a string representing the current browser.
+* @property browser
+* @type String
+*/
+YAHOO.widget.Calendar.prototype.browser = function() {
+			var ua = navigator.userAgent.toLowerCase();
+				  if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
+					 return 'opera';
+				  } else if (ua.indexOf('msie 7')!=-1) { // IE7
+					 return 'ie7';
+				  } else if (ua.indexOf('msie') !=-1) { // IE
+					 return 'ie';
+				  } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
+					 return 'safari';
+				  } else if (ua.indexOf('gecko') != -1) { // Gecko
+					 return 'gecko';
+				  } else {
+					 return false;
+				  }
+			}();
+/**
+* Returns a string representation of the object.
+* @method toString
+* @return {String}	A string representation of the Calendar object.
+*/
+YAHOO.widget.Calendar.prototype.toString = function() {
+	return "Calendar " + this.id;
+};
+
+/**
+* @namespace YAHOO.widget
+* @class Calendar_Core
+* @extends YAHOO.widget.Calendar
+* @deprecated The old Calendar_Core class is no longer necessary.
+*/
+YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;
+
+YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
+
+/**
+* YAHOO.widget.CalendarGroup is a special container class for YAHOO.widget.Calendar. This class facilitates
+* the ability to have multi-page calendar views that share a single dataset and are
+* dependent on each other.
+* 
+* The calendar group instance will refer to each of its elements using a 0-based index.
+* For example, to construct the placeholder for a calendar group widget with id "cal1" and
+* containerId of "cal1Container", the markup would be as follows:
+*	<xmp>
+*		<div id="cal1Container_0"></div>
+*		<div id="cal1Container_1"></div>
+*	</xmp>
+* The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
+* @namespace YAHOO.widget
+* @class CalendarGroup
+* @constructor
+* @param {String}	id			The id of the table element that will represent the calendar widget
+* @param {String}	containerId	The id of the container div element that will wrap the calendar table
+* @param {Object}	config		The configuration object containing the Calendar's arguments
+*/
+YAHOO.widget.CalendarGroup = function(id, containerId, config) {
+	if (arguments.length > 0) {
+		this.init(id, containerId, config);
+	}
+};
+
+/**
+* Initializes the calendar group. All subclasses must call this method in order for the
+* group to be initialized properly.
+* @method init
+* @param {String}	id			The id of the table element that will represent the calendar widget
+* @param {String}	containerId	The id of the container div element that will wrap the calendar table
+* @param {Object}	config		The configuration object containing the Calendar's arguments
+*/
+YAHOO.widget.CalendarGroup.prototype.init = function(id, containerId, config) {
+	this.initEvents();
+	this.initStyles();
+
+	/**
+	* The collection of Calendar pages contained within the CalendarGroup
+	* @property pages
+	* @type YAHOO.widget.Calendar[]
+	*/
+	this.pages = [];
+	
+	/**
+	* The unique id associated with the CalendarGroup
+	* @property id
+	* @type String
+	*/
+	this.id = id;
+
+	/**
+	* The unique id associated with the CalendarGroup container
+	* @property containerId
+	* @type String
+	*/
+	this.containerId = containerId;
+
+	/**
+	* The outer containing element for the CalendarGroup
+	* @property oDomContainer
+	* @type HTMLElement
+	*/
+	this.oDomContainer = document.getElementById(containerId);
+
+	YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_CONTAINER);
+	YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_MULTI_UP);
+
+	/**
+	* The Config object used to hold the configuration variables for the CalendarGroup
+	* @property cfg
+	* @type YAHOO.util.Config
+	*/
+	this.cfg = new YAHOO.util.Config(this);
+
+	/**
+	* The local object which contains the CalendarGroup's options
+	* @property Options
+	* @type Object
+	*/
+	this.Options = {};
+
+	/**
+	* The local object which contains the CalendarGroup's locale settings
+	* @property Locale
+	* @type Object
+	*/
+	this.Locale = {};
+
+	this.setupConfig();
+
+	if (config) {
+		this.cfg.applyConfig(config, true);
+	}
+
+	this.cfg.fireQueue();
+
+	// OPERA HACK FOR MISWRAPPED FLOATS
+	if (this.browser == "opera"){
+		var fixWidth = function() {
+			var startW = this.oDomContainer.offsetWidth;
+			var w = 0;
+			for (var p=0;p<this.pages.length;++p) {
+				var cal = this.pages[p];
+				w += cal.oDomContainer.offsetWidth;
+			}
+			if (w > 0) {
+				this.oDomContainer.style.width = w + "px";
+			}
+		};
+		this.renderEvent.subscribe(fixWidth,this,true);
+	}
+};
+
+
+YAHOO.widget.CalendarGroup.prototype.setupConfig = function() {
+	
+	var defCfg = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG;
+	
+	/**
+	* The number of pages to include in the CalendarGroup. This value can only be set once, in the CalendarGroup's constructor arguments.
+	* @config pages
+	* @type Number
+	* @default 2
+	*/
+	this.cfg.addProperty(defCfg.PAGES.key, { value:defCfg.PAGES.value, validator:this.cfg.checkNumber, handler:this.configPages } );
+
+	/**
+	* The month/year representing the current visible Calendar date (mm/yyyy)
+	* @config pagedate
+	* @type String
+	* @default today's date
+	*/
+	this.cfg.addProperty(defCfg.PAGEDATE.key, { value:defCfg.PAGEDATE.value, handler:this.configPageDate } );
+
+	/**
+	* The date or range of dates representing the current Calendar selection
+	* @config selected
+	* @type String
+	* @default []
+	*/
+	this.cfg.addProperty(defCfg.SELECTED.key, { value:defCfg.SELECTED.value, handler:this.configSelected } );
+
+	/**
+	* The title to display above the CalendarGroup's month header
+	* @config title
+	* @type String
+	* @default ""
+	*/
+	this.cfg.addProperty(defCfg.TITLE.key, { value:defCfg.TITLE.value, handler:this.configTitle } );
+
+	/**
+	* Whether or not a close button should be displayed for this CalendarGroup
+	* @config close
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(defCfg.CLOSE.key, { value:defCfg.CLOSE.value, handler:this.configClose } );
+
+	/**
+	* Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
+	* @config iframe
+	* @type Boolean
+	* @default true
+	*/
+	this.cfg.addProperty(defCfg.IFRAME.key, { value:defCfg.IFRAME.value, handler:this.configIframe, validator:this.cfg.checkBoolean } );
+
+	/**
+	* The minimum selectable date in the current Calendar (mm/dd/yyyy)
+	* @config mindate
+	* @type String
+	* @default null
+	*/
+	this.cfg.addProperty(defCfg.MINDATE.key, { value:defCfg.MINDATE.value, handler:this.delegateConfig } );
+
+	/**
+	* The maximum selectable date in the current Calendar (mm/dd/yyyy)
+	* @config maxdate
+	* @type String
+	* @default null
+	*/	
+	this.cfg.addProperty(defCfg.MAXDATE.key, { value:defCfg.MAXDATE.value, handler:this.delegateConfig  } );
+
+	// Options properties
+
+	/**
+	* True if the Calendar should allow multiple selections. False by default.
+	* @config MULTI_SELECT
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(defCfg.MULTI_SELECT.key,	{ value:defCfg.MULTI_SELECT.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+
+	/**
+	* The weekday the week begins on. Default is 0 (Sunday).
+	* @config START_WEEKDAY
+	* @type number
+	* @default 0
+	*/	
+	this.cfg.addProperty(defCfg.START_WEEKDAY.key,	{ value:defCfg.START_WEEKDAY.value, handler:this.delegateConfig, validator:this.cfg.checkNumber  } );
+	
+	/**
+	* True if the Calendar should show weekday labels. True by default.
+	* @config SHOW_WEEKDAYS
+	* @type Boolean
+	* @default true
+	*/	
+	this.cfg.addProperty(defCfg.SHOW_WEEKDAYS.key,	{ value:defCfg.SHOW_WEEKDAYS.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+	
+	/**
+	* True if the Calendar should show week row headers. False by default.
+	* @config SHOW_WEEK_HEADER
+	* @type Boolean
+	* @default false
+	*/	
+	this.cfg.addProperty(defCfg.SHOW_WEEK_HEADER.key,{ value:defCfg.SHOW_WEEK_HEADER.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+	
+	/**
+	* True if the Calendar should show week row footers. False by default.
+	* @config SHOW_WEEK_FOOTER
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(defCfg.SHOW_WEEK_FOOTER.key,{ value:defCfg.SHOW_WEEK_FOOTER.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+	
+	/**
+	* True if the Calendar should suppress weeks that are not a part of the current month. False by default.
+	* @config HIDE_BLANK_WEEKS
+	* @type Boolean
+	* @default false
+	*/		
+	this.cfg.addProperty(defCfg.HIDE_BLANK_WEEKS.key,{ value:defCfg.HIDE_BLANK_WEEKS.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+	
+	/**
+	* The image that should be used for the left navigation arrow.
+	* @config NAV_ARROW_LEFT
+	* @type String
+	* @deprecated	You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
+	* @default null
+	*/		
+	this.cfg.addProperty(defCfg.NAV_ARROW_LEFT.key,	{ value:defCfg.NAV_ARROW_LEFT.value, handler:this.delegateConfig } );
+	
+	/**
+	* The image that should be used for the right navigation arrow.
+	* @config NAV_ARROW_RIGHT
+	* @type String
+	* @deprecated	You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
+	* @default null
+	*/		
+	this.cfg.addProperty(defCfg.NAV_ARROW_RIGHT.key,	{ value:defCfg.NAV_ARROW_RIGHT.value, handler:this.delegateConfig } );
+
+	// Locale properties
+	
+	/**
+	* The short month labels for the current locale.
+	* @config MONTHS_SHORT
+	* @type String[]
+	* @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+	*/
+	this.cfg.addProperty(defCfg.MONTHS_SHORT.key,	{ value:defCfg.MONTHS_SHORT.value, handler:this.delegateConfig } );
+	
+	/**
+	* The long month labels for the current locale.
+	* @config MONTHS_LONG
+	* @type String[]
+	* @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+	*/		
+	this.cfg.addProperty(defCfg.MONTHS_LONG.key,		{ value:defCfg.MONTHS_LONG.value, handler:this.delegateConfig } );
+	
+	/**
+	* The 1-character weekday labels for the current locale.
+	* @config WEEKDAYS_1CHAR
+	* @type String[]
+	* @default ["S", "M", "T", "W", "T", "F", "S"]
+	*/		
+	this.cfg.addProperty(defCfg.WEEKDAYS_1CHAR.key,	{ value:defCfg.WEEKDAYS_1CHAR.value, handler:this.delegateConfig } );
+	
+	/**
+	* The short weekday labels for the current locale.
+	* @config WEEKDAYS_SHORT
+	* @type String[]
+	* @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
+	*/		
+	this.cfg.addProperty(defCfg.WEEKDAYS_SHORT.key,	{ value:defCfg.WEEKDAYS_SHORT.value, handler:this.delegateConfig } );
+	
+	/**
+	* The medium weekday labels for the current locale.
+	* @config WEEKDAYS_MEDIUM
+	* @type String[]
+	* @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+	*/		
+	this.cfg.addProperty(defCfg.WEEKDAYS_MEDIUM.key,	{ value:defCfg.WEEKDAYS_MEDIUM.value, handler:this.delegateConfig } );
+	
+	/**
+	* The long weekday labels for the current locale.
+	* @config WEEKDAYS_LONG
+	* @type String[]
+	* @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+	*/		
+	this.cfg.addProperty(defCfg.WEEKDAYS_LONG.key,	{ value:defCfg.WEEKDAYS_LONG.value, handler:this.delegateConfig } );
+
+	/**
+	* The setting that determines which length of month labels should be used. Possible values are "short" and "long".
+	* @config LOCALE_MONTHS
+	* @type String
+	* @default "long"
+	*/
+	this.cfg.addProperty(defCfg.LOCALE_MONTHS.key,	{ value:defCfg.LOCALE_MONTHS.value, handler:this.delegateConfig } );
+
+	/**
+	* The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
+	* @config LOCALE_WEEKDAYS
+	* @type String
+	* @default "short"
+	*/	
+	this.cfg.addProperty(defCfg.LOCALE_WEEKDAYS.key,	{ value:defCfg.LOCALE_WEEKDAYS.value, handler:this.delegateConfig } );
+
+	/**
+	* The value used to delimit individual dates in a date string passed to various Calendar functions.
+	* @config DATE_DELIMITER
+	* @type String
+	* @default ","
+	*/
+	this.cfg.addProperty(defCfg.DATE_DELIMITER.key,		{ value:defCfg.DATE_DELIMITER.value, handler:this.delegateConfig } );
+
+	/**
+	* The value used to delimit date fields in a date string passed to various Calendar functions.
+	* @config DATE_FIELD_DELIMITER
+	* @type String
+	* @default "/"
+	*/	
+	this.cfg.addProperty(defCfg.DATE_FIELD_DELIMITER.key,{ value:defCfg.DATE_FIELD_DELIMITER.value, handler:this.delegateConfig } );
+
+	/**
+	* The value used to delimit date ranges in a date string passed to various Calendar functions.
+	* @config DATE_RANGE_DELIMITER
+	* @type String
+	* @default "-"
+	*/
+	this.cfg.addProperty(defCfg.DATE_RANGE_DELIMITER.key,{ value:defCfg.DATE_RANGE_DELIMITER.value, handler:this.delegateConfig } );
+
+	/**
+	* The position of the month in a month/year date string
+	* @config MY_MONTH_POSITION
+	* @type Number
+	* @default 1
+	*/
+	this.cfg.addProperty(defCfg.MY_MONTH_POSITION.key,	{ value:defCfg.MY_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+	
+	/**
+	* The position of the year in a month/year date string
+	* @config MY_YEAR_POSITION
+	* @type Number
+	* @default 2
+	*/	
+	this.cfg.addProperty(defCfg.MY_YEAR_POSITION.key,	{ value:defCfg.MY_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+	
+	/**
+	* The position of the month in a month/day date string
+	* @config MD_MONTH_POSITION
+	* @type Number
+	* @default 1
+	*/	
+	this.cfg.addProperty(defCfg.MD_MONTH_POSITION.key,	{ value:defCfg.MD_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+	
+	/**
+	* The position of the day in a month/year date string
+	* @config MD_DAY_POSITION
+	* @type Number
+	* @default 2
+	*/	
+	this.cfg.addProperty(defCfg.MD_DAY_POSITION.key,		{ value:defCfg.MD_DAY_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+	
+	/**
+	* The position of the month in a month/day/year date string
+	* @config MDY_MONTH_POSITION
+	* @type Number
+	* @default 1
+	*/	
+	this.cfg.addProperty(defCfg.MDY_MONTH_POSITION.key,	{ value:defCfg.MDY_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+	
+	/**
+	* The position of the day in a month/day/year date string
+	* @config MDY_DAY_POSITION
+	* @type Number
+	* @default 2
+	*/	
+	this.cfg.addProperty(defCfg.MDY_DAY_POSITION.key,	{ value:defCfg.MDY_DAY_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+	
+	/**
+	* The position of the year in a month/day/year date string
+	* @config MDY_YEAR_POSITION
+	* @type Number
+	* @default 3
+	*/	
+	this.cfg.addProperty(defCfg.MDY_YEAR_POSITION.key,	{ value:defCfg.MDY_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+
+};
+
+/**
+* Initializes CalendarGroup's built-in CustomEvents
+* @method initEvents
+*/
+YAHOO.widget.CalendarGroup.prototype.initEvents = function() {
+	var me = this;
+	var strEvent = "Event";
+
+	/**
+	* Proxy subscriber to subscribe to the CalendarGroup's child Calendars' CustomEvents
+	* @method sub
+	* @private
+	* @param {Function} fn	The function to subscribe to this CustomEvent
+	* @param {Object}	obj	The CustomEvent's scope object
+	* @param {Boolean}	bOverride	Whether or not to apply scope correction
+	*/
+	var sub = function(fn, obj, bOverride) {
+		for (var p=0;p<me.pages.length;++p) {
+			var cal = me.pages[p];
+			cal[this.type + strEvent].subscribe(fn, obj, bOverride);
+		}
+	};
+
+	/**
+	* Proxy unsubscriber to unsubscribe from the CalendarGroup's child Calendars' CustomEvents
+	* @method unsub
+	* @private
+	* @param {Function} fn	The function to subscribe to this CustomEvent
+	* @param {Object}	obj	The CustomEvent's scope object
+	*/
+	var unsub = function(fn, obj) {
+		for (var p=0;p<me.pages.length;++p) {
+			var cal = me.pages[p];
+			cal[this.type + strEvent].unsubscribe(fn, obj);
+		}
+	};
+	
+	var defEvents = YAHOO.widget.Calendar._EVENT_TYPES;
+
+	/**
+	* Fired before a selection is made
+	* @event beforeSelectEvent
+	*/
+	this.beforeSelectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_SELECT);
+	this.beforeSelectEvent.subscribe = sub; this.beforeSelectEvent.unsubscribe = unsub;
+
+	/**
+	* Fired when a selection is made
+	* @event selectEvent
+	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
+	*/
+	this.selectEvent = new YAHOO.util.CustomEvent(defEvents.SELECT); 
+	this.selectEvent.subscribe = sub; this.selectEvent.unsubscribe = unsub;
+
+	/**
+	* Fired before a selection is made
+	* @event beforeDeselectEvent
+	*/
+	this.beforeDeselectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_DESELECT); 
+	this.beforeDeselectEvent.subscribe = sub; this.beforeDeselectEvent.unsubscribe = unsub;
+
+	/**
+	* Fired when a selection is made
+	* @event deselectEvent
+	* @param {Array}	Array of Date field arrays in the format [YYYY, MM, DD].
+	*/
+	this.deselectEvent = new YAHOO.util.CustomEvent(defEvents.DESELECT); 
+	this.deselectEvent.subscribe = sub; this.deselectEvent.unsubscribe = unsub;
+	
+	/**
+	* Fired when the Calendar page is changed
+	* @event changePageEvent
+	*/
+	this.changePageEvent = new YAHOO.util.CustomEvent(defEvents.CHANGE_PAGE); 
+	this.changePageEvent.subscribe = sub; this.changePageEvent.unsubscribe = unsub;
+
+	/**
+	* Fired before the Calendar is rendered
+	* @event beforeRenderEvent
+	*/
+	this.beforeRenderEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_RENDER);
+	this.beforeRenderEvent.subscribe = sub; this.beforeRenderEvent.unsubscribe = unsub;
+
+	/**
+	* Fired when the Calendar is rendered
+	* @event renderEvent
+	*/
+	this.renderEvent = new YAHOO.util.CustomEvent(defEvents.RENDER);
+	this.renderEvent.subscribe = sub; this.renderEvent.unsubscribe = unsub;
+
+	/**
+	* Fired when the Calendar is reset
+	* @event resetEvent
+	*/
+	this.resetEvent = new YAHOO.util.CustomEvent(defEvents.RESET); 
+	this.resetEvent.subscribe = sub; this.resetEvent.unsubscribe = unsub;
+
+	/**
+	* Fired when the Calendar is cleared
+	* @event clearEvent
+	*/
+	this.clearEvent = new YAHOO.util.CustomEvent(defEvents.CLEAR);
+	this.clearEvent.subscribe = sub; this.clearEvent.unsubscribe = unsub;
+
+};
+
+/**
+* The default Config handler for the "pages" property
+* @method configPages
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.CalendarGroup.prototype.configPages = function(type, args, obj) {
+	var pageCount = args[0];
+
+	var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
+
+	// Define literals outside loop	
+	var sep = "_";
+	var groupCalClass = "groupcal";
+	var firstClass = "first";
+	var lastClass = "last";
+
+	for (var p=0;p<pageCount;++p) {
+		var calId = this.id + sep + p;
+		var calContainerId = this.containerId + sep + p;
+
+		var childConfig = this.cfg.getConfig();
+		childConfig.close = false;
+		childConfig.title = false;
+
+		var cal = this.constructChild(calId, calContainerId, childConfig);
+		var caldate = cal.cfg.getProperty(cfgPageDate);
+		this._setMonthOnDate(caldate, caldate.getMonth() + p);
+		cal.cfg.setProperty(cfgPageDate, caldate);
+		
+		YAHOO.util.Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
+		YAHOO.util.Dom.addClass(cal.oDomContainer, groupCalClass);
+		
+		if (p===0) {
+			YAHOO.util.Dom.addClass(cal.oDomContainer, firstClass);
+		}
+
+		if (p==(pageCount-1)) {
+			YAHOO.util.Dom.addClass(cal.oDomContainer, lastClass);
+		}
+		
+		cal.parent = this;
+		cal.index = p; 
+
+		this.pages[this.pages.length] = cal;
+	}
+};
+
+/**
+* The default Config handler for the "pagedate" property
+* @method configPageDate
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.CalendarGroup.prototype.configPageDate = function(type, args, obj) {
+	var val = args[0];
+	var firstPageDate;
+	
+	var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
+	
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		if (p === 0) {
+			firstPageDate = cal._parsePageDate(val);
+			cal.cfg.setProperty(cfgPageDate, firstPageDate);
+		} else {
+			var pageDate = new Date(firstPageDate);
+			this._setMonthOnDate(pageDate, pageDate.getMonth() + p);
+			cal.cfg.setProperty(cfgPageDate, pageDate);
+		}
+	}
+};
+
+/**
+* The default Config handler for the CalendarGroup "selected" property
+* @method configSelected
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.CalendarGroup.prototype.configSelected = function(type, args, obj) {
+	var cfgSelected = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key;
+	this.delegateConfig(type, args, obj);
+	var selected = (this.pages.length > 0) ? this.pages[0].cfg.getProperty(cfgSelected) : []; 
+	this.cfg.setProperty(cfgSelected, selected, true);
+};
+
+
+/**
+* Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
+* @method delegateConfig
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.CalendarGroup.prototype.delegateConfig = function(type, args, obj) {
+	var val = args[0];
+	var cal;
+
+	for (var p=0;p<this.pages.length;p++) {
+		cal = this.pages[p];
+		cal.cfg.setProperty(type, val);
+	}
+};
+
+
+/**
+* Adds a function to all child Calendars within this CalendarGroup.
+* @method setChildFunction
+* @param {String}		fnName		The name of the function
+* @param {Function}		fn			The function to apply to each Calendar page object
+*/
+YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
+	var pageCount = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);
+
+	for (var p=0;p<pageCount;++p) {
+		this.pages[p][fnName] = fn;
+	}
+};
+
+/**
+* Calls a function within all child Calendars within this CalendarGroup.
+* @method callChildFunction
+* @param {String}		fnName		The name of the function
+* @param {Array}		args		The arguments to pass to the function
+*/
+YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {
+	var pageCount = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);
+
+	for (var p=0;p<pageCount;++p) {
+		var page = this.pages[p];
+		if (page[fnName]) {
+			var fn = page[fnName];
+			fn.call(page, args);
+		}
+	}	
+};
+
+/**
+* Constructs a child calendar. This method can be overridden if a subclassed version of the default
+* calendar is to be used.
+* @method constructChild
+* @param {String}	id			The id of the table element that will represent the calendar widget
+* @param {String}	containerId	The id of the container div element that will wrap the calendar table
+* @param {Object}	config		The configuration object containing the Calendar's arguments
+* @return {YAHOO.widget.Calendar}	The YAHOO.widget.Calendar instance that is constructed
+*/
+YAHOO.widget.CalendarGroup.prototype.constructChild = function(id,containerId,config) {
+	var container = document.getElementById(containerId);
+	if (! container) {
+		container = document.createElement("div");
+		container.id = containerId;
+		this.oDomContainer.appendChild(container);
+	}
+	return new YAHOO.widget.Calendar(id,containerId,config);
+};
+
+
+/**
+* Sets the calendar group's month explicitly. This month will be set into the first
+* page of the multi-page calendar, and all other months will be iterated appropriately.
+* @method setMonth
+* @param {Number}	month		The numeric month, from 0 (January) to 11 (December)
+*/
+YAHOO.widget.CalendarGroup.prototype.setMonth = function(month) {
+	month = parseInt(month, 10);
+	var currYear;
+	
+	var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
+	
+	for (var p=0; p<this.pages.length; ++p) {
+		var cal = this.pages[p];
+		var pageDate = cal.cfg.getProperty(cfgPageDate);
+		if (p === 0) {
+			currYear = pageDate.getFullYear();
+		} else {
+			pageDate.setYear(currYear);
+		}
+		this._setMonthOnDate(pageDate, month+p); 
+		cal.cfg.setProperty(cfgPageDate, pageDate);
+	}
+};
+
+/**
+* Sets the calendar group's year explicitly. This year will be set into the first
+* page of the multi-page calendar, and all other months will be iterated appropriately.
+* @method setYear
+* @param {Number}	year		The numeric 4-digit year
+*/
+YAHOO.widget.CalendarGroup.prototype.setYear = function(year) {
+
+	var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
+
+	year = parseInt(year, 10);
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		var pageDate = cal.cfg.getProperty(cfgPageDate);
+
+		if ((pageDate.getMonth()+1) == 1 && p>0) {
+			year+=1;
+		}
+		cal.setYear(year);
+	}
+};
+/**
+* Calls the render function of all child calendars within the group.
+* @method render
+*/
+YAHOO.widget.CalendarGroup.prototype.render = function() {
+	this.renderHeader();
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.render();
+	}
+	this.renderFooter();
+};
+
+/**
+* Selects a date or a collection of dates on the current calendar. This method, by default,
+* does not call the render method explicitly. Once selection has completed, render must be 
+* called for the changes to be reflected visually.
+* @method select
+* @param	{String/Date/Date[]}	date	The date string of dates to select in the current calendar. Valid formats are
+*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
+*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
+*								This method can also take a JavaScript Date object or an array of Date objects.
+* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.CalendarGroup.prototype.select = function(date) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.select(date);
+	}
+	return this.getSelectedDates();
+};
+
+/**
+* Selects dates in the CalendarGroup based on the cell index provided. This method is used to select cells without having to do a full render. The selected style is applied to the cells directly.
+* The value of the MULTI_SELECT Configuration attribute will determine the set of dates which get selected. 
+* <ul>
+*    <li>If MULTI_SELECT is false, selectCell will select the cell at the specified index for only the last displayed Calendar page.</li>
+*    <li>If MULTI_SELECT is true, selectCell will select the cell at the specified index, on each displayed Calendar page.</li>
+* </ul>
+* @method selectCell
+* @param	{Number}	cellIndex	The index of the cell to be selected. 
+* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.selectCell(cellIndex);
+	}
+	return this.getSelectedDates();
+};
+
+/**
+* Deselects a date or a collection of dates on the current calendar. This method, by default,
+* does not call the render method explicitly. Once deselection has completed, render must be 
+* called for the changes to be reflected visually.
+* @method deselect
+* @param	{String/Date/Date[]}	date	The date string of dates to deselect in the current calendar. Valid formats are
+*								individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
+*								Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
+*								This method can also take a JavaScript Date object or an array of Date objects.	
+* @return	{Date[]}			Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.CalendarGroup.prototype.deselect = function(date) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.deselect(date);
+	}
+	return this.getSelectedDates();
+};
+
+/**
+* Deselects all dates on the current calendar.
+* @method deselectAll
+* @return {Date[]}		Array of JavaScript Date objects representing all individual dates that are currently selected.
+*						Assuming that this function executes properly, the return value should be an empty array.
+*						However, the empty array is returned for the sake of being able to check the selection status
+*						of the calendar.
+*/
+YAHOO.widget.CalendarGroup.prototype.deselectAll = function() {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.deselectAll();
+	}
+	return this.getSelectedDates();
+};
+
+/**
+* Deselects dates in the CalendarGroup based on the cell index provided. This method is used to select cells without having to do a full render. The selected style is applied to the cells directly.
+* deselectCell will deselect the cell at the specified index on each displayed Calendar page.
+*
+* @method deselectCell
+* @param	{Number}	cellIndex	The index of the cell to deselect. 
+* @return	{Date[]}	Array of JavaScript Date objects representing all individual dates that are currently selected.
+*/
+YAHOO.widget.CalendarGroup.prototype.deselectCell = function(cellIndex) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.deselectCell(cellIndex);
+	}
+	return this.getSelectedDates();
+};
+
+/**
+* Resets the calendar widget to the originally selected month and year, and 
+* sets the calendar to the initial selection(s).
+* @method reset
+*/
+YAHOO.widget.CalendarGroup.prototype.reset = function() {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.reset();
+	}
+};
+
+/**
+* Clears the selected dates in the current calendar widget and sets the calendar
+* to the current month and year.
+* @method clear
+*/
+YAHOO.widget.CalendarGroup.prototype.clear = function() {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.clear();
+	}
+};
+
+/**
+* Navigates to the next month page in the calendar widget.
+* @method nextMonth
+*/
+YAHOO.widget.CalendarGroup.prototype.nextMonth = function() {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.nextMonth();
+	}
+};
+
+/**
+* Navigates to the previous month page in the calendar widget.
+* @method previousMonth
+*/
+YAHOO.widget.CalendarGroup.prototype.previousMonth = function() {
+	for (var p=this.pages.length-1;p>=0;--p) {
+		var cal = this.pages[p];
+		cal.previousMonth();
+	}
+};
+
+/**
+* Navigates to the next year in the currently selected month in the calendar widget.
+* @method nextYear
+*/
+YAHOO.widget.CalendarGroup.prototype.nextYear = function() {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.nextYear();
+	}
+};
+
+/**
+* Navigates to the previous year in the currently selected month in the calendar widget.
+* @method previousYear
+*/
+YAHOO.widget.CalendarGroup.prototype.previousYear = function() {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.previousYear();
+	}
+};
+
+
+/**
+* Gets the list of currently selected dates from the calendar.
+* @return			An array of currently selected JavaScript Date objects.
+* @type Date[]
+*/
+YAHOO.widget.CalendarGroup.prototype.getSelectedDates = function() { 
+	var returnDates = [];
+	var selected = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key);
+	for (var d=0;d<selected.length;++d) {
+		var dateArray = selected[d];
+
+		var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
+		returnDates.push(date);
+	}
+
+	returnDates.sort( function(a,b) { return a-b; } );
+	return returnDates;
+};
+
+/**
+* Adds a renderer to the render stack. The function reference passed to this method will be executed
+* when a date cell matches the conditions specified in the date string for this renderer.
+* @method addRenderer
+* @param	{String}	sDates		A date string to associate with the specified renderer. Valid formats
+*									include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.CalendarGroup.prototype.addRenderer = function(sDates, fnRender) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.addRenderer(sDates, fnRender);
+	}
+};
+
+/**
+* Adds a month to the render stack. The function reference passed to this method will be executed
+* when a date cell matches the month passed to this method.
+* @method addMonthRenderer
+* @param	{Number}	month		The month (1-12) to associate with this renderer
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.CalendarGroup.prototype.addMonthRenderer = function(month, fnRender) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.addMonthRenderer(month, fnRender);
+	}
+};
+
+/**
+* Adds a weekday to the render stack. The function reference passed to this method will be executed
+* when a date cell matches the weekday passed to this method.
+* @method addWeekdayRenderer
+* @param	{Number}	weekday		The weekday (0-6) to associate with this renderer
+* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
+*/
+YAHOO.widget.CalendarGroup.prototype.addWeekdayRenderer = function(weekday, fnRender) {
+	for (var p=0;p<this.pages.length;++p) {
+		var cal = this.pages[p];
+		cal.addWeekdayRenderer(weekday, fnRender);
+	}
+};
+
+/**
+* Renders the header for the CalendarGroup.
+* @method renderHeader
+*/
+YAHOO.widget.CalendarGroup.prototype.renderHeader = function() {};
+
+/**
+* Renders a footer for the 2-up calendar container. By default, this method is
+* unimplemented.
+* @method renderFooter
+*/
+YAHOO.widget.CalendarGroup.prototype.renderFooter = function() {};
+
+/**
+* Adds the designated number of months to the current calendar month, and sets the current
+* calendar page date to the new month.
+* @method addMonths
+* @param {Number}	count	The number of months to add to the current calendar
+*/
+YAHOO.widget.CalendarGroup.prototype.addMonths = function(count) {
+	this.callChildFunction("addMonths", count);
+};
+
+
+/**
+* Subtracts the designated number of months from the current calendar month, and sets the current
+* calendar page date to the new month.
+* @method subtractMonths
+* @param {Number}	count	The number of months to subtract from the current calendar
+*/
+YAHOO.widget.CalendarGroup.prototype.subtractMonths = function(count) {
+	this.callChildFunction("subtractMonths", count);
+};
+
+/**
+* Adds the designated number of years to the current calendar, and sets the current
+* calendar page date to the new month.
+* @method addYears
+* @param {Number}	count	The number of years to add to the current calendar
+*/
+YAHOO.widget.CalendarGroup.prototype.addYears = function(count) {
+	this.callChildFunction("addYears", count);
+};
+
+/**
+* Subtcats the designated number of years from the current calendar, and sets the current
+* calendar page date to the new month.
+* @method subtractYears
+* @param {Number}	count	The number of years to subtract from the current calendar
+*/
+YAHOO.widget.CalendarGroup.prototype.subtractYears = function(count) {
+	this.callChildFunction("subtractYears", count);
+};
+
+/**
+* Sets the month on a Date object, taking into account year rollover if the month is less than 0 or greater than 11.
+* The Date object passed in is modified. It should be cloned before passing it into this method if the original value needs to be maintained
+* @method	_setMonthOnDate
+* @private
+* @param	{Date}	date	The Date object on which to set the month index
+* @param	{Number}	iMonth	The month index to set
+*/
+YAHOO.widget.CalendarGroup.prototype._setMonthOnDate = function(date, iMonth) {
+	// BUG in Safari 1.3, 2.0 (WebKit build < 420), Date.setMonth does not work consistently if iMonth is not 0-11
+	if (this.browser == "safari" && (iMonth < 0 || iMonth > 11)) {
+		var DM = YAHOO.widget.DateMath;
+		var newDate = DM.add(date, DM.MONTH, iMonth-date.getMonth());
+		date.setTime(newDate.getTime());
+	} else {
+		date.setMonth(iMonth);
+	}
+};
+
+
+/**
+* CSS class representing the container for the calendar
+* @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
+
+/**
+* CSS class representing the container for the calendar
+* @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.CalendarGroup.CSS_MULTI_UP = "multi";
+
+/**
+* CSS class representing the title for the 2-up calendar
+* @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.CalendarGroup.CSS_2UPTITLE = "title";
+
+/**
+* CSS class representing the close icon for the 2-up calendar
+* @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
+* @static
+* @final
+* @deprecated	Along with Calendar.IMG_ROOT and NAV_ARROW_LEFT, NAV_ARROW_RIGHT configuration properties.
+*					Calendar's <a href="YAHOO.widget.Calendar.html#Style.CSS_CLOSE">Style.CSS_CLOSE</a> property now represents the CSS class used to render the close icon
+* @type String
+*/
+YAHOO.widget.CalendarGroup.CSS_2UPCLOSE = "close-icon";
+
+YAHOO.augment(YAHOO.widget.CalendarGroup, YAHOO.widget.Calendar, "buildDayLabel",
+																 "buildMonthLabel",
+																 "renderOutOfBoundsDate",
+																 "renderRowHeader",
+																 "renderRowFooter",
+																 "renderCellDefault",
+																 "styleCellDefault",
+																 "renderCellStyleHighlight1",
+																 "renderCellStyleHighlight2",
+																 "renderCellStyleHighlight3",
+																 "renderCellStyleHighlight4",
+																 "renderCellStyleToday",
+																 "renderCellStyleSelected",
+																 "renderCellNotThisMonth",
+																 "renderBodyCellRestricted",
+																 "initStyles",
+																 "configTitle",
+																 "configClose",
+																 "configIframe",
+																 "hide",
+																 "show",
+																 "browser");
+
+/**
+* The set of default Config property keys and values for the CalendarGroup
+* @property YAHOO.widget.CalendarGroup._DEFAULT_CONFIG
+* @final
+* @static
+* @private
+* @type Object
+*/
+YAHOO.widget.CalendarGroup._DEFAULT_CONFIG = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES = {key:"pages", value:2};
+
+/**
+* Returns a string representation of the object.
+* @method toString
+* @return {String}	A string representation of the CalendarGroup object.
+*/
+YAHOO.widget.CalendarGroup.prototype.toString = function() {
+	return "CalendarGroup " + this.id;
+};
+
+YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;
+
+/**
+* @class YAHOO.widget.Calendar2up
+* @extends YAHOO.widget.CalendarGroup
+* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
+*/
+YAHOO.widget.Calendar2up = function(id, containerId, config) {
+	this.init(id, containerId, config);
+};
+
+YAHOO.extend(YAHOO.widget.Calendar2up, YAHOO.widget.CalendarGroup);
+
+/**
+* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
+*/
+YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;
+
+YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.2.1", build: "193"});

Modified: jifty/branches/virtual-models/share/web/static/js/yui/container.js
==============================================================================
--- jifty/branches/virtual-models/share/web/static/js/yui/container.js	(original)
+++ jifty/branches/virtual-models/share/web/static/js/yui/container.js	Mon May  7 16:28:32 2007
@@ -1,4614 +1,5398 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version 0.12.1
-*/
-
-/**
-* Config is a utility used within an Object to allow the implementer to maintain a list of local configuration properties and listen for changes to those properties dynamically using CustomEvent. The initial values are also maintained so that the configuration can be reset at any given point to its initial state.
-* @namespace YAHOO.util
-* @class Config
-* @constructor
-* @param {Object}	owner	The owner Object to which this Config Object belongs
-*/
-YAHOO.util.Config = function(owner) {
-	if (owner) {
-		this.init(owner);
-	}
-};
-
-YAHOO.util.Config.prototype = {
-
-	/**
-	* Object reference to the owner of this Config Object
-	* @property owner
-	* @type Object
-	*/
-	owner : null,
-
-	/**
-	* Boolean flag that specifies whether a queue is currently being executed
-	* @property queueInProgress
-	* @type Boolean
-	*/
-	queueInProgress : false,
-
-
-	/**
-	* Validates that the value passed in is a Boolean.
-	* @method checkBoolean
-	* @param	{Object}	val	The value to validate
-	* @return	{Boolean}	true, if the value is valid
-	*/
-	checkBoolean: function(val) {
-		if (typeof val == 'boolean') {
-			return true;
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	* Validates that the value passed in is a number.
-	* @method checkNumber
-	* @param	{Object}	val	The value to validate
-	* @return	{Boolean}	true, if the value is valid
-	*/
-	checkNumber: function(val) {
-		if (isNaN(val)) {
-			return false;
-		} else {
-			return true;
-		}
-	}
-};
-
-
-/**
-* Initializes the configuration Object and all of its local members.
-* @method init
-* @param {Object}	owner	The owner Object to which this Config Object belongs
-*/
-YAHOO.util.Config.prototype.init = function(owner) {
-
-	this.owner = owner;
-
-	/**
-	* Object reference to the owner of this Config Object
-	* @event configChangedEvent
-	*/
-	this.configChangedEvent = new YAHOO.util.CustomEvent("configChanged");
-
-	this.queueInProgress = false;
-
-	/* Private Members */
-
-	/**
-	* Maintains the local collection of configuration property objects and their specified values
-	* @property config
-	* @private
-	* @type Object
-	*/
-	var config = {};
-
-	/**
-	* Maintains the local collection of configuration property objects as they were initially applied.
-	* This object is used when resetting a property.
-	* @property initialConfig
-	* @private
-	* @type Object
-	*/
-	var initialConfig = {};
-
-	/**
-	* Maintains the local, normalized CustomEvent queue
-	* @property eventQueue
-	* @private
-	* @type Object
-	*/
-	var eventQueue = [];
-
-	/**
-	* Fires a configuration property event using the specified value.
-	* @method fireEvent
-	* @private
-	* @param {String}	key			The configuration property's name
-	* @param {value}	Object		The value of the correct type for the property
-	*/
-	var fireEvent = function( key, value ) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-
-		if (typeof property != 'undefined' && property.event) {
-			property.event.fire(value);
-		}
-	};
-	/* End Private Members */
-
-	/**
-	* Adds a property to the Config Object's private config hash.
-	* @method addProperty
-	* @param {String}	key	The configuration property's name
-	* @param {Object}	propertyObject	The Object containing all of this property's arguments
-	*/
-	this.addProperty = function( key, propertyObject ) {
-		key = key.toLowerCase();
-
-		config[key] = propertyObject;
-
-		propertyObject.event = new YAHOO.util.CustomEvent(key);
-		propertyObject.key = key;
-
-		if (propertyObject.handler) {
-			propertyObject.event.subscribe(propertyObject.handler, this.owner, true);
-		}
-
-		this.setProperty(key, propertyObject.value, true);
-
-		if (! propertyObject.suppressEvent) {
-			this.queueProperty(key, propertyObject.value);
-		}
-	};
-
-	/**
-	* Returns a key-value configuration map of the values currently set in the Config Object.
-	* @method getConfig
-	* @return {Object} The current config, represented in a key-value map
-	*/
-	this.getConfig = function() {
-		var cfg = {};
-
-		for (var prop in config) {
-			var property = config[prop];
-			if (typeof property != 'undefined' && property.event) {
-				cfg[prop] = property.value;
-			}
-		}
-
-		return cfg;
-	};
-
-	/**
-	* Returns the value of specified property.
-	* @method getProperty
-	* @param {String} key	The name of the property
-	* @return {Object}		The value of the specified property
-	*/
-	this.getProperty = function(key) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			return property.value;
-		} else {
-			return undefined;
-		}
-	};
-
-	/**
-	* Resets the specified property's value to its initial value.
-	* @method resetProperty
-	* @param {String} key	The name of the property
-	* @return {Boolean} True is the property was reset, false if not
-	*/
-	this.resetProperty = function(key) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			if (initialConfig[key] && initialConfig[key] != 'undefined')	{
-				this.setProperty(key, initialConfig[key]);
-			}
-			return true;
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Sets the value of a property. If the silent property is passed as true, the property's event will not be fired.
-	* @method setProperty
-	* @param {String} key		The name of the property
-	* @param {String} value		The value to set the property to
-	* @param {Boolean} silent	Whether the value should be set silently, without firing the property event.
-	* @return {Boolean}			True, if the set was successful, false if it failed.
-	*/
-	this.setProperty = function(key, value, silent) {
-		key = key.toLowerCase();
-
-		if (this.queueInProgress && ! silent) {
-			this.queueProperty(key,value); // Currently running through a queue...
-			return true;
-		} else {
-			var property = config[key];
-			if (typeof property != 'undefined' && property.event) {
-				if (property.validator && ! property.validator(value)) { // validator
-					return false;
-				} else {
-					property.value = value;
-					if (! silent) {
-						fireEvent(key, value);
-						this.configChangedEvent.fire([key, value]);
-					}
-					return true;
-				}
-			} else {
-				return false;
-			}
-		}
-	};
-
-	/**
-	* Sets the value of a property and queues its event to execute. If the event is already scheduled to execute, it is
-	* moved from its current position to the end of the queue.
-	* @method queueProperty
-	* @param {String} key	The name of the property
-	* @param {String} value	The value to set the property to
-	* @return {Boolean}		true, if the set was successful, false if it failed.
-	*/
-	this.queueProperty = function(key, value) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-
-		if (typeof property != 'undefined' && property.event) {
-			if (typeof value != 'undefined' && property.validator && ! property.validator(value)) { // validator
-				return false;
-			} else {
-
-				if (typeof value != 'undefined') {
-					property.value = value;
-				} else {
-					value = property.value;
-				}
-
-				var foundDuplicate = false;
-
-				for (var i=0;i<eventQueue.length;i++) {
-					var queueItem = eventQueue[i];
-
-					if (queueItem) {
-						var queueItemKey = queueItem[0];
-						var queueItemValue = queueItem[1];
-
-						if (queueItemKey.toLowerCase() == key) {
-							// found a dupe... push to end of queue, null current item, and break
-							eventQueue[i] = null;
-							eventQueue.push([key, (typeof value != 'undefined' ? value : queueItemValue)]);
-							foundDuplicate = true;
-							break;
-						}
-					}
-				}
-
-				if (! foundDuplicate && typeof value != 'undefined') { // this is a refire, or a new property in the queue
-					eventQueue.push([key, value]);
-				}
-			}
-
-			if (property.supercedes) {
-				for (var s=0;s<property.supercedes.length;s++) {
-					var supercedesCheck = property.supercedes[s];
-
-					for (var q=0;q<eventQueue.length;q++) {
-						var queueItemCheck = eventQueue[q];
-
-						if (queueItemCheck) {
-							var queueItemCheckKey = queueItemCheck[0];
-							var queueItemCheckValue = queueItemCheck[1];
-
-							if ( queueItemCheckKey.toLowerCase() == supercedesCheck.toLowerCase() ) {
-								eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
-								eventQueue[q] = null;
-								break;
-							}
-						}
-					}
-				}
-			}
-
-			return true;
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Fires the event for a property using the property's current value.
-	* @method refireEvent
-	* @param {String} key	The name of the property
-	*/
-	this.refireEvent = function(key) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event && typeof property.value != 'undefined') {
-			if (this.queueInProgress) {
-				this.queueProperty(key);
-			} else {
-				fireEvent(key, property.value);
-			}
-		}
-	};
-
-	/**
-	* Applies a key-value Object literal to the configuration, replacing any existing values, and queueing the property events.
-	* Although the values will be set, fireQueue() must be called for their associated events to execute.
-	* @method applyConfig
-	* @param {Object}	userConfig	The configuration Object literal
-	* @param {Boolean}	init		When set to true, the initialConfig will be set to the userConfig passed in, so that calling a reset will reset the properties to the passed values.
-	*/
-	this.applyConfig = function(userConfig, init) {
-		if (init) {
-			initialConfig = userConfig;
-		}
-		for (var prop in userConfig) {
-			this.queueProperty(prop, userConfig[prop]);
-		}
-	};
-
-	/**
-	* Refires the events for all configuration properties using their current values.
-	* @method refresh
-	*/
-	this.refresh = function() {
-		for (var prop in config) {
-			this.refireEvent(prop);
-		}
-	};
-
-	/**
-	* Fires the normalized list of queued property change events
-	* @method fireQueue
-	*/
-	this.fireQueue = function() {
-		this.queueInProgress = true;
-		for (var i=0;i<eventQueue.length;i++) {
-			var queueItem = eventQueue[i];
-			if (queueItem) {
-				var key = queueItem[0];
-				var value = queueItem[1];
-
-				var property = config[key];
-				property.value = value;
-
-				fireEvent(key,value);
-			}
-		}
-
-		this.queueInProgress = false;
-		eventQueue = [];
-	};
-
-	/**
-	* Subscribes an external handler to the change event for any given property.
-	* @method subscribeToConfigEvent
-	* @param {String}	key			The property name
-	* @param {Function}	handler		The handler function to use subscribe to the property's event
-	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
-	* @param {Boolean}	override	Optional. If true, will override "this" within the handler to map to the scope Object passed into the method.
-	* @return {Boolean}				True, if the subscription was successful, otherwise false.
-	*/
-	this.subscribeToConfigEvent = function(key, handler, obj, override) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, obj)) {
-				property.event.subscribe(handler, obj, override);
-			}
-			return true;
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Unsubscribes an external handler from the change event for any given property.
-	* @method unsubscribeFromConfigEvent
-	* @param {String}	key			The property name
-	* @param {Function}	handler		The handler function to use subscribe to the property's event
-	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
-	* @return {Boolean}				True, if the unsubscription was successful, otherwise false.
-	*/
-	this.unsubscribeFromConfigEvent = function(key, handler, obj) {
-		key = key.toLowerCase();
-
-		var property = config[key];
-		if (typeof property != 'undefined' && property.event) {
-			return property.event.unsubscribe(handler, obj);
-		} else {
-			return false;
-		}
-	};
-
-	/**
-	* Returns a string representation of the Config object
-	* @method toString
-	* @return {String}	The Config object in string format.
-	*/
-	this.toString = function() {
-		var output = "Config";
-		if (this.owner) {
-			output += " [" + this.owner.toString() + "]";
-		}
-		return output;
-	};
-
-	/**
-	* Returns a string representation of the Config object's current CustomEvent queue
-	* @method outputEventQueue
-	* @return {String}	The string list of CustomEvents currently queued for execution
-	*/
-	this.outputEventQueue = function() {
-		var output = "";
-		for (var q=0;q<eventQueue.length;q++) {
-			var queueItem = eventQueue[q];
-			if (queueItem) {
-				output += queueItem[0] + "=" + queueItem[1] + ", ";
-			}
-		}
-		return output;
-	};
-};
-
-/**
-* Checks to determine if a particular function/Object pair are already subscribed to the specified CustomEvent
-* @method YAHOO.util.Config.alreadySubscribed
-* @static
-* @param {YAHOO.util.CustomEvent} evt	The CustomEvent for which to check the subscriptions
-* @param {Function}	fn	The function to look for in the subscribers list
-* @param {Object}	obj	The execution scope Object for the subscription
-* @return {Boolean}	true, if the function/Object pair is already subscribed to the CustomEvent passed in
-*/
-YAHOO.util.Config.alreadySubscribed = function(evt, fn, obj) {
-	for (var e=0;e<evt.subscribers.length;e++) {
-		var subsc = evt.subscribers[e];
-		if (subsc && subsc.obj == obj && subsc.fn == fn) {
-			return true;
-		}
-	}
-	return false;
-};
-
-/**
-*  The Container family of components is designed to enable developers to create different kinds of content-containing modules on the web. Module and Overlay are the most basic containers, and they can be used directly or extended to build custom containers. Also part of the Container family are four UI controls that extend Module and Overlay: Tooltip, Panel, Dialog, and SimpleDialog.
-* @module container
-* @title Container
-* @requires yahoo,dom,event,dragdrop,animation
-*/
-
-/**
-* Module is a JavaScript representation of the Standard Module Format. Standard Module Format is a simple standard for markup containers where child nodes representing the header, body, and footer of the content are denoted using the CSS classes "hd", "bd", and "ft" respectively. Module is the base class for all other classes in the YUI Container package.
-* @namespace YAHOO.widget
-* @class Module
-* @constructor
-* @param {String} el			The element ID representing the Module <em>OR</em>
-* @param {HTMLElement} el		The element representing the Module
-* @param {Object} userConfig	The configuration Object literal containing the configuration that should be set for this module. See configuration documentation for more details.
-*/
-YAHOO.widget.Module = function(el, userConfig) {
-	if (el) {
-		this.init(el, userConfig);
-	}
-};
-
-/**
-* Constant representing the prefix path to use for non-secure images
-* @property YAHOO.widget.Module.IMG_ROOT
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.IMG_ROOT = "http://us.i1.yimg.com/us.yimg.com/i/";
-
-/**
-* Constant representing the prefix path to use for securely served images
-* @property YAHOO.widget.Module.IMG_ROOT_SSL
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.IMG_ROOT_SSL = "https://a248.e.akamai.net/sec.yimg.com/i/";
-
-/**
-* Constant for the default CSS class name that represents a Module
-* @property YAHOO.widget.Module.CSS_MODULE
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.CSS_MODULE = "module";
-
-/**
-* Constant representing the module header
-* @property YAHOO.widget.Module.CSS_HEADER
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.CSS_HEADER = "hd";
-
-/**
-* Constant representing the module body
-* @property YAHOO.widget.Module.CSS_BODY
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.CSS_BODY = "bd";
-
-/**
-* Constant representing the module footer
-* @property YAHOO.widget.Module.CSS_FOOTER
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.CSS_FOOTER = "ft";
-
-/**
-* Constant representing the url for the "src" attribute of the iframe used to monitor changes to the browser's base font size
-* @property YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL = "javascript:false;";
-
-/**
-* Singleton CustomEvent fired when the font size is changed in the browser.
-* Opera's "zoom" functionality currently does not support text size detection.
-* @event YAHOO.widget.Module.textResizeEvent
-*/
-YAHOO.widget.Module.textResizeEvent = new YAHOO.util.CustomEvent("textResize");
-
-YAHOO.widget.Module.prototype = {
-	/**
-	* The class's constructor function
-	* @property contructor
-	* @type Function
-	*/
-	constructor : YAHOO.widget.Module,
-
-	/**
-	* The main module element that contains the header, body, and footer
-	* @property element
-	* @type HTMLElement
-	*/
-	element : null,
-
-	/**
-	* The header element, denoted with CSS class "hd"
-	* @property header
-	* @type HTMLElement
-	*/
-	header : null,
-
-	/**
-	* The body element, denoted with CSS class "bd"
-	* @property body
-	* @type HTMLElement
-	*/
-	body : null,
-
-	/**
-	* The footer element, denoted with CSS class "ft"
-	* @property footer
-	* @type HTMLElement
-	*/
-	footer : null,
-
-	/**
-	* The id of the element
-	* @property id
-	* @type String
-	*/
-	id : null,
-
-	/**
-	* The String representing the image root
-	* @property imageRoot
-	* @type String
-	*/
-	imageRoot : YAHOO.widget.Module.IMG_ROOT,
-
-	/**
-	* Initializes the custom events for Module which are fired automatically at appropriate times by the Module class.
-	* @method initEvents
-	*/
-	initEvents : function() {
-
-		/**
-		* CustomEvent fired prior to class initalization.
-		* @event beforeInitEvent
-		* @param {class} classRef	class reference of the initializing class, such as this.beforeInitEvent.fire(YAHOO.widget.Module)
-		*/
-		this.beforeInitEvent = new YAHOO.util.CustomEvent("beforeInit");
-
-		/**
-		* CustomEvent fired after class initalization.
-		* @event initEvent
-		* @param {class} classRef	class reference of the initializing class, such as this.beforeInitEvent.fire(YAHOO.widget.Module)
-		*/
-		this.initEvent = new YAHOO.util.CustomEvent("init");
-
-		/**
-		* CustomEvent fired when the Module is appended to the DOM
-		* @event appendEvent
-		*/
-		this.appendEvent = new YAHOO.util.CustomEvent("append");
-
-		/**
-		* CustomEvent fired before the Module is rendered
-		* @event beforeRenderEvent
-		*/
-		this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
-
-		/**
-		* CustomEvent fired after the Module is rendered
-		* @event renderEvent
-		*/
-		this.renderEvent = new YAHOO.util.CustomEvent("render");
-
-		/**
-		* CustomEvent fired when the header content of the Module is modified
-		* @event changeHeaderEvent
-		* @param {String/HTMLElement} content	String/element representing the new header content
-		*/
-		this.changeHeaderEvent = new YAHOO.util.CustomEvent("changeHeader");
-
-		/**
-		* CustomEvent fired when the body content of the Module is modified
-		* @event changeBodyEvent
-		* @param {String/HTMLElement} content	String/element representing the new body content
-		*/
-		this.changeBodyEvent = new YAHOO.util.CustomEvent("changeBody");
-
-		/**
-		* CustomEvent fired when the footer content of the Module is modified
-		* @event changeFooterEvent
-		* @param {String/HTMLElement} content	String/element representing the new footer content
-		*/
-		this.changeFooterEvent = new YAHOO.util.CustomEvent("changeFooter");
-
-		/**
-		* CustomEvent fired when the content of the Module is modified
-		* @event changeContentEvent
-		*/
-		this.changeContentEvent = new YAHOO.util.CustomEvent("changeContent");
-
-		/**
-		* CustomEvent fired when the Module is destroyed
-		* @event destroyEvent
-		*/
-		this.destroyEvent = new YAHOO.util.CustomEvent("destroy");
-
-		/**
-		* CustomEvent fired before the Module is shown
-		* @event beforeShowEvent
-		*/
-		this.beforeShowEvent = new YAHOO.util.CustomEvent("beforeShow");
-
-		/**
-		* CustomEvent fired after the Module is shown
-		* @event showEvent
-		*/
-		this.showEvent = new YAHOO.util.CustomEvent("show");
-
-		/**
-		* CustomEvent fired before the Module is hidden
-		* @event beforeHideEvent
-		*/
-		this.beforeHideEvent = new YAHOO.util.CustomEvent("beforeHide");
-
-		/**
-		* CustomEvent fired after the Module is hidden
-		* @event hideEvent
-		*/
-		this.hideEvent = new YAHOO.util.CustomEvent("hide");
-	},
-
-	/**
-	* String representing the current user-agent platform
-	* @property platform
-	* @type String
-	*/
-	platform : function() {
-					var ua = navigator.userAgent.toLowerCase();
-					if (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1) {
-						return "windows";
-					} else if (ua.indexOf("macintosh") != -1) {
-						return "mac";
-					} else {
-						return false;
-					}
-				}(),
-
-	/**
-	* String representing the current user-agent browser
-	* @property browser
-	* @type String
-	*/
-	browser : function() {
-			var ua = navigator.userAgent.toLowerCase();
-				  if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
-					 return 'opera';
-				  } else if (ua.indexOf('msie 7')!=-1) { // IE7
-					 return 'ie7';
-				  } else if (ua.indexOf('msie') !=-1) { // IE
-					 return 'ie';
-				  } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
-					 return 'safari';
-				  } else if (ua.indexOf('gecko') != -1) { // Gecko
-					 return 'gecko';
-				  } else {
-					 return false;
-				  }
-			}(),
-
-	/**
-	* Boolean representing whether or not the current browsing context is secure (https)
-	* @property isSecure
-	* @type Boolean
-	*/
-	isSecure : function() {
-		if (window.location.href.toLowerCase().indexOf("https") === 0) {
-			return true;
-		} else {
-			return false;
-		}
-	}(),
-
-	/**
-	* Initializes the custom events for Module which are fired automatically at appropriate times by the Module class.
-	*/
-	initDefaultConfig : function() {
-		// Add properties //
-
-		/**
-		* Specifies whether the Module is visible on the page.
-		* @config visible
-		* @type Boolean
-		* @default true
-		*/
-		this.cfg.addProperty("visible", { value:true, handler:this.configVisible, validator:this.cfg.checkBoolean } );
-
-		/**
-		* Object or array of objects representing the ContainerEffect classes that are active for animating the container.
-		* @config effect
-		* @type Object
-		* @default null
-		*/
-		this.cfg.addProperty("effect", { suppressEvent:true, supercedes:["visible"] } );
-
-		/**
-		* Specifies whether to create a special proxy iframe to monitor for user font resizing in the document
-		* @config monitorresize
-		* @type Boolean
-		* @default true
-		*/
-		this.cfg.addProperty("monitorresize", { value:true, handler:this.configMonitorResize } );
-	},
-
-	/**
-	* The Module class's initialization method, which is executed for Module and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
-	* @method init
-	* @param {String}	el	The element ID representing the Module <em>OR</em>
-	* @param {HTMLElement}	el	The element representing the Module
-	* @param {Object}	userConfig	The configuration Object literal containing the configuration that should be set for this module. See configuration documentation for more details.
-	*/
-	init : function(el, userConfig) {
-
-		this.initEvents();
-
-		this.beforeInitEvent.fire(YAHOO.widget.Module);
-
-		/**
-		* The Module's Config object used for monitoring configuration properties.
-		* @property cfg
-		* @type YAHOO.util.Config
-		*/
-		this.cfg = new YAHOO.util.Config(this);
-
-		if (this.isSecure) {
-			this.imageRoot = YAHOO.widget.Module.IMG_ROOT_SSL;
-		}
-
-		if (typeof el == "string") {
-			var elId = el;
-
-			el = document.getElementById(el);
-			if (! el) {
-				el = document.createElement("DIV");
-				el.id = elId;
-			}
-		}
-
-		this.element = el;
-
-		if (el.id) {
-			this.id = el.id;
-		}
-
-		var childNodes = this.element.childNodes;
-
-		if (childNodes) {
-			for (var i=0;i<childNodes.length;i++) {
-				var child = childNodes[i];
-				switch (child.className) {
-					case YAHOO.widget.Module.CSS_HEADER:
-						this.header = child;
-						break;
-					case YAHOO.widget.Module.CSS_BODY:
-						this.body = child;
-						break;
-					case YAHOO.widget.Module.CSS_FOOTER:
-						this.footer = child;
-						break;
-				}
-			}
-		}
-
-		this.initDefaultConfig();
-
-		YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Module.CSS_MODULE);
-
-		if (userConfig) {
-			this.cfg.applyConfig(userConfig, true);
-		}
-
-		// Subscribe to the fireQueue() method of Config so that any queued configuration changes are
-		// excecuted upon render of the Module
-		if (! YAHOO.util.Config.alreadySubscribed(this.renderEvent, this.cfg.fireQueue, this.cfg)) {
-			this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true);
-		}
-
-		this.initEvent.fire(YAHOO.widget.Module);
-	},
-
-	/**
-	* Initialized an empty IFRAME that is placed out of the visible area that can be used to detect text resize.
-	* @method initResizeMonitor
-	*/
-	initResizeMonitor : function() {
-
-        if(this.browser != "opera") {
-
-            var resizeMonitor = document.getElementById("_yuiResizeMonitor");
-
-            if (! resizeMonitor) {
-
-                resizeMonitor = document.createElement("iframe");
-
-                var bIE = (this.browser.indexOf("ie") === 0);
-
-                if(this.isSecure &&
-                   YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL &&
-                   bIE) {
-
-                  resizeMonitor.src =
-                       YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL;
-
-                }
-
-                resizeMonitor.id = "_yuiResizeMonitor";
-                resizeMonitor.style.visibility = "hidden";
-
-                document.body.appendChild(resizeMonitor);
-
-                resizeMonitor.style.width = "10em";
-                resizeMonitor.style.height = "10em";
-                resizeMonitor.style.position = "absolute";
-
-                var nLeft = -1 * resizeMonitor.offsetWidth,
-                    nTop = -1 * resizeMonitor.offsetHeight;
-
-                resizeMonitor.style.top = nTop + "px";
-                resizeMonitor.style.left =  nLeft + "px";
-                resizeMonitor.style.borderStyle = "none";
-                resizeMonitor.style.borderWidth = "0";
-                YAHOO.util.Dom.setStyle(resizeMonitor, "opacity", "0");
-
-                resizeMonitor.style.visibility = "visible";
-
-                if(!bIE) {
-
-                    var doc = resizeMonitor.contentWindow.document;
-
-                    doc.open();
-                    doc.close();
-
-                }
-            }
-
-			var fireTextResize = function() {
-				YAHOO.widget.Module.textResizeEvent.fire();
-			};
-
-            if(resizeMonitor && resizeMonitor.contentWindow) {
-                this.resizeMonitor = resizeMonitor;
-
-				YAHOO.widget.Module.textResizeEvent.subscribe(this.onDomResize, this, true);
-
-				if (! YAHOO.widget.Module.textResizeInitialized) {
-					if (! YAHOO.util.Event.addListener(this.resizeMonitor.contentWindow, "resize", fireTextResize)) {
-						// This will fail in IE if document.domain has changed, so we must change the listener to
-						// use the resizeMonitor element instead
-						YAHOO.util.Event.addListener(this.resizeMonitor, "resize", fireTextResize);
-					}
-					YAHOO.widget.Module.textResizeInitialized = true;
-				}
-            }
-
-        }
-
-	},
-
-	/**
-	* Event handler fired when the resize monitor element is resized.
-	* @method onDomResize
-	* @param {DOMEvent} e	The DOM resize event
-	* @param {Object} obj	The scope object passed to the handler
-	*/
-	onDomResize : function(e, obj) {
-
-        var nLeft = -1 * this.resizeMonitor.offsetWidth,
-            nTop = -1 * this.resizeMonitor.offsetHeight;
-
-        this.resizeMonitor.style.top = nTop + "px";
-        this.resizeMonitor.style.left =  nLeft + "px";
-
-	},
-
-	/**
-	* Sets the Module's header content to the HTML specified, or appends the passed element to the header. If no header is present, one will be automatically created.
-	* @method setHeader
-	* @param {String}	headerContent	The HTML used to set the header <em>OR</em>
-	* @param {HTMLElement}	headerContent	The HTMLElement to append to the header
-	*/
-	setHeader : function(headerContent) {
-		if (! this.header) {
-			this.header = document.createElement("DIV");
-			this.header.className = YAHOO.widget.Module.CSS_HEADER;
-		}
-
-		if (typeof headerContent == "string") {
-			this.header.innerHTML = headerContent;
-		} else {
-			this.header.innerHTML = "";
-			this.header.appendChild(headerContent);
-		}
-
-		this.changeHeaderEvent.fire(headerContent);
-		this.changeContentEvent.fire();
-	},
-
-	/**
-	* Appends the passed element to the header. If no header is present, one will be automatically created.
-	* @method appendToHeader
-	* @param {HTMLElement}	element	The element to append to the header
-	*/
-	appendToHeader : function(element) {
-		if (! this.header) {
-			this.header = document.createElement("DIV");
-			this.header.className = YAHOO.widget.Module.CSS_HEADER;
-		}
-
-		this.header.appendChild(element);
-		this.changeHeaderEvent.fire(element);
-		this.changeContentEvent.fire();
-	},
-
-	/**
-	* Sets the Module's body content to the HTML specified, or appends the passed element to the body. If no body is present, one will be automatically created.
-	* @method setBody
-	* @param {String}	bodyContent	The HTML used to set the body <em>OR</em>
-	* @param {HTMLElement}	bodyContent	The HTMLElement to append to the body
-	*/
-	setBody : function(bodyContent) {
-		if (! this.body) {
-			this.body = document.createElement("DIV");
-			this.body.className = YAHOO.widget.Module.CSS_BODY;
-		}
-
-		if (typeof bodyContent == "string")
-		{
-			this.body.innerHTML = bodyContent;
-		} else {
-			this.body.innerHTML = "";
-			this.body.appendChild(bodyContent);
-		}
-
-		this.changeBodyEvent.fire(bodyContent);
-		this.changeContentEvent.fire();
-	},
-
-	/**
-	* Appends the passed element to the body. If no body is present, one will be automatically created.
-	* @method appendToBody
-	* @param {HTMLElement}	element	The element to append to the body
-	*/
-	appendToBody : function(element) {
-		if (! this.body) {
-			this.body = document.createElement("DIV");
-			this.body.className = YAHOO.widget.Module.CSS_BODY;
-		}
-
-		this.body.appendChild(element);
-		this.changeBodyEvent.fire(element);
-		this.changeContentEvent.fire();
-	},
-
-	/**
-	* Sets the Module's footer content to the HTML specified, or appends the passed element to the footer. If no footer is present, one will be automatically created.
-	* @method setFooter
-	* @param {String}	footerContent	The HTML used to set the footer <em>OR</em>
-	* @param {HTMLElement}	footerContent	The HTMLElement to append to the footer
-	*/
-	setFooter : function(footerContent) {
-		if (! this.footer) {
-			this.footer = document.createElement("DIV");
-			this.footer.className = YAHOO.widget.Module.CSS_FOOTER;
-		}
-
-		if (typeof footerContent == "string") {
-			this.footer.innerHTML = footerContent;
-		} else {
-			this.footer.innerHTML = "";
-			this.footer.appendChild(footerContent);
-		}
-
-		this.changeFooterEvent.fire(footerContent);
-		this.changeContentEvent.fire();
-	},
-
-	/**
-	* Appends the passed element to the footer. If no footer is present, one will be automatically created.
-	* @method appendToFooter
-	* @param {HTMLElement}	element	The element to append to the footer
-	*/
-	appendToFooter : function(element) {
-		if (! this.footer) {
-			this.footer = document.createElement("DIV");
-			this.footer.className = YAHOO.widget.Module.CSS_FOOTER;
-		}
-
-		this.footer.appendChild(element);
-		this.changeFooterEvent.fire(element);
-		this.changeContentEvent.fire();
-	},
-
-	/**
-	* Renders the Module by inserting the elements that are not already in the main Module into their correct places. Optionally appends the Module to the specified node prior to the render's execution. NOTE: For Modules without existing markup, the appendToNode argument is REQUIRED. If this argument is ommitted and the current element is not present in the document, the function will return false, indicating that the render was a failure.
-	* @method render
-	* @param {String}	appendToNode	The element id to which the Module should be appended to prior to rendering <em>OR</em>
-	* @param {HTMLElement}	appendToNode	The element to which the Module should be appended to prior to rendering
-	* @param {HTMLElement}	moduleElement	OPTIONAL. The element that represents the actual Standard Module container.
-	* @return {Boolean} Success or failure of the render
-	*/
-	render : function(appendToNode, moduleElement) {
-		this.beforeRenderEvent.fire();
-
-		if (! moduleElement) {
-			moduleElement = this.element;
-		}
-
-		var me = this;
-		var appendTo = function(element) {
-			if (typeof element == "string") {
-				element = document.getElementById(element);
-			}
-
-			if (element) {
-				element.appendChild(me.element);
-				me.appendEvent.fire();
-			}
-		};
-
-		if (appendToNode) {
-			appendTo(appendToNode);
-		} else { // No node was passed in. If the element is not pre-marked up, this fails
-			if (! YAHOO.util.Dom.inDocument(this.element)) {
-				return false;
-			}
-		}
-
-		// Need to get everything into the DOM if it isn't already
-
-		if (this.header && ! YAHOO.util.Dom.inDocument(this.header)) {
-			// There is a header, but it's not in the DOM yet... need to add it
-			var firstChild = moduleElement.firstChild;
-			if (firstChild) { // Insert before first child if exists
-				moduleElement.insertBefore(this.header, firstChild);
-			} else { // Append to empty body because there are no children
-				moduleElement.appendChild(this.header);
-			}
-		}
-
-		if (this.body && ! YAHOO.util.Dom.inDocument(this.body)) {
-			// There is a body, but it's not in the DOM yet... need to add it
-			if (this.footer && YAHOO.util.Dom.isAncestor(this.moduleElement, this.footer)) { // Insert before footer if exists in DOM
-				moduleElement.insertBefore(this.body, this.footer);
-			} else { // Append to element because there is no footer
-				moduleElement.appendChild(this.body);
-			}
-		}
-
-		if (this.footer && ! YAHOO.util.Dom.inDocument(this.footer)) {
-			// There is a footer, but it's not in the DOM yet... need to add it
-			moduleElement.appendChild(this.footer);
-		}
-
-		this.renderEvent.fire();
-		return true;
-	},
-
-	/**
-	* Removes the Module element from the DOM and sets all child elements to null.
-	* @method destroy
-	*/
-	destroy : function() {
-		var parent;
-
-		if (this.element) {
-			YAHOO.util.Event.purgeElement(this.element, true);
-			parent = this.element.parentNode;
-		}
-		if (parent) {
-			parent.removeChild(this.element);
-		}
-
-		this.element = null;
-		this.header = null;
-		this.body = null;
-		this.footer = null;
-
-		for (var e in this) {
-			if (e instanceof YAHOO.util.CustomEvent) {
-				e.unsubscribeAll();
-			}
-		}
-
-		YAHOO.widget.Module.textResizeEvent.unsubscribe(this.onDomResize, this);
-
-		this.destroyEvent.fire();
-	},
-
-	/**
-	* Shows the Module element by setting the visible configuration property to true. Also fires two events: beforeShowEvent prior to the visibility change, and showEvent after.
-	* @method show
-	*/
-	show : function() {
-		this.cfg.setProperty("visible", true);
-	},
-
-	/**
-	* Hides the Module element by setting the visible configuration property to false. Also fires two events: beforeHideEvent prior to the visibility change, and hideEvent after.
-	* @method hide
-	*/
-	hide : function() {
-		this.cfg.setProperty("visible", false);
-	},
-
-	// BUILT-IN EVENT HANDLERS FOR MODULE //
-
-	/**
-	* Default event handler for changing the visibility property of a Module. By default, this is achieved by switching the "display" style between "block" and "none".
-	* This method is responsible for firing showEvent and hideEvent.
-	* @param {String} type	The CustomEvent type (usually the property name)
-	* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-	* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-	* @method configVisible
-	*/
-	configVisible : function(type, args, obj) {
-		var visible = args[0];
-		if (visible) {
-			this.beforeShowEvent.fire();
-			YAHOO.util.Dom.setStyle(this.element, "display", "block");
-			this.showEvent.fire();
-		} else {
-			this.beforeHideEvent.fire();
-			YAHOO.util.Dom.setStyle(this.element, "display", "none");
-			this.hideEvent.fire();
-		}
-	},
-
-	/**
-	* Default event handler for the "monitorresize" configuration property
-	* @param {String} type	The CustomEvent type (usually the property name)
-	* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-	* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-	* @method configMonitorResize
-	*/
-	configMonitorResize : function(type, args, obj) {
-		var monitor = args[0];
-		if (monitor) {
-			this.initResizeMonitor();
-		} else {
-			YAHOO.util.Event.removeListener(this.resizeMonitor, "resize", this.onDomResize);
-			this.resizeMonitor = null;
-		}
-	}
-};
-
-/**
-* Returns a String representation of the Object.
-* @method toString
-* @return {String}	The string representation of the Module
-*/
-YAHOO.widget.Module.prototype.toString = function() {
-	return "Module " + this.id;
-};
-
-/**
-* Overlay is a Module that is absolutely positioned above the page flow. It has convenience methods for positioning and sizing, as well as options for controlling zIndex and constraining the Overlay's position to the current visible viewport. Overlay also contains a dynamicly generated IFRAME which is placed beneath it for Internet Explorer 6 and 5.x so that it will be properly rendered above SELECT elements.
-* @namespace YAHOO.widget
-* @class Overlay
-* @extends YAHOO.widget.Module
-* @param {String}	el	The element ID representing the Overlay <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Overlay
-* @param {Object}	userConfig	The configuration object literal containing 10/23/2006the configuration that should be set for this Overlay. See configuration documentation for more details.
-* @constructor
-*/
-YAHOO.widget.Overlay = function(el, userConfig) {
-	YAHOO.widget.Overlay.superclass.constructor.call(this, el, userConfig);
-};
-
-YAHOO.extend(YAHOO.widget.Overlay, YAHOO.widget.Module);
-
-/**
-* The URL that will be placed in the iframe
-* @property YAHOO.widget.Overlay.IFRAME_SRC
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Overlay.IFRAME_SRC = "javascript:false;";
-
-/**
-* Constant representing the top left corner of an element, used for configuring the context element alignment
-* @property YAHOO.widget.Overlay.TOP_LEFT
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Overlay.TOP_LEFT = "tl";
-
-/**
-* Constant representing the top right corner of an element, used for configuring the context element alignment
-* @property YAHOO.widget.Overlay.TOP_RIGHT
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Overlay.TOP_RIGHT = "tr";
-
-/**
-* Constant representing the top bottom left corner of an element, used for configuring the context element alignment
-* @property YAHOO.widget.Overlay.BOTTOM_LEFT
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Overlay.BOTTOM_LEFT = "bl";
-
-/**
-* Constant representing the bottom right corner of an element, used for configuring the context element alignment
-* @property YAHOO.widget.Overlay.BOTTOM_RIGHT
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Overlay.BOTTOM_RIGHT = "br";
-
-/**
-* Constant representing the default CSS class used for an Overlay
-* @property YAHOO.widget.Overlay.CSS_OVERLAY
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Overlay.CSS_OVERLAY = "overlay";
-
-/**
-* The Overlay initialization method, which is executed for Overlay and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
-* @method init
-* @param {String}	el	The element ID representing the Overlay <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Overlay
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Overlay. See configuration documentation for more details.
-*/
-YAHOO.widget.Overlay.prototype.init = function(el, userConfig) {
-	YAHOO.widget.Overlay.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
-
-	this.beforeInitEvent.fire(YAHOO.widget.Overlay);
-
-	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Overlay.CSS_OVERLAY);
-
-	if (userConfig) {
-		this.cfg.applyConfig(userConfig, true);
-	}
-
-	if (this.platform == "mac" && this.browser == "gecko") {
-		if (! YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)) {
-			this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);
-		}
-		if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)) {
-			this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);
-		}
-	}
-
-	this.initEvent.fire(YAHOO.widget.Overlay);
-};
-
-/**
-* Initializes the custom events for Overlay which are fired automatically at appropriate times by the Overlay class.
-* @method initEvents
-*/
-YAHOO.widget.Overlay.prototype.initEvents = function() {
-	YAHOO.widget.Overlay.superclass.initEvents.call(this);
-
-	/**
-	* CustomEvent fired before the Overlay is moved.
-	* @event beforeMoveEvent
-	* @param {Number} x	x coordinate
-	* @param {Number} y	y coordinate
-	*/
-	this.beforeMoveEvent = new YAHOO.util.CustomEvent("beforeMove", this);
-
-	/**
-	* CustomEvent fired after the Overlay is moved.
-	* @event moveEvent
-	* @param {Number} x	x coordinate
-	* @param {Number} y	y coordinate
-	*/
-	this.moveEvent = new YAHOO.util.CustomEvent("move", this);
-};
-
-/**
-* Initializes the class's configurable properties which can be changed using the Overlay's Config object (cfg).
-* @method initDefaultConfig
-*/
-YAHOO.widget.Overlay.prototype.initDefaultConfig = function() {
-	YAHOO.widget.Overlay.superclass.initDefaultConfig.call(this);
-
-	// Add overlay config properties //
-
-	/**
-	* The absolute x-coordinate position of the Overlay
-	* @config x
-	* @type Number
-	* @default null
-	*/
-	this.cfg.addProperty("x", { handler:this.configX, validator:this.cfg.checkNumber, suppressEvent:true, supercedes:["iframe"] } );
-
-	/**
-	* The absolute y-coordinate position of the Overlay
-	* @config y
-	* @type Number
-	* @default null
-	*/
-	this.cfg.addProperty("y", { handler:this.configY, validator:this.cfg.checkNumber, suppressEvent:true, supercedes:["iframe"] } );
-
-	/**
-	* An array with the absolute x and y positions of the Overlay
-	* @config xy
-	* @type Number[]
-	* @default null
-	*/
-	this.cfg.addProperty("xy",{ handler:this.configXY, suppressEvent:true, supercedes:["iframe"] } );
-
-	/**
-	* The array of context arguments for context-sensitive positioning. The format is: [id or element, element corner, context corner]. For example, setting this property to ["img1", "tl", "bl"] would align the Overlay's top left corner to the context element's bottom left corner.
-	* @config context
-	* @type Array
-	* @default null
-	*/
-	this.cfg.addProperty("context",	{ handler:this.configContext, suppressEvent:true, supercedes:["iframe"] } );
-
-	/**
-	* True if the Overlay should be anchored to the center of the viewport.
-	* @config fixedcenter
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("fixedcenter", { value:false, handler:this.configFixedCenter, validator:this.cfg.checkBoolean, supercedes:["iframe","visible"] } );
-
-	/**
-	* CSS width of the Overlay.
-	* @config width
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("width", { handler:this.configWidth, suppressEvent:true, supercedes:["iframe"] } );
-
-	/**
-	* CSS height of the Overlay.
-	* @config height
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("height", { handler:this.configHeight, suppressEvent:true, supercedes:["iframe"] } );
-
-	/**
-	* CSS z-index of the Overlay.
-	* @config zIndex
-	* @type Number
-	* @default null
-	*/
-	this.cfg.addProperty("zIndex", { value:null, handler:this.configzIndex } );
-
-	/**
-	* True if the Overlay should be prevented from being positioned out of the viewport.
-	* @config constraintoviewport
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("constraintoviewport", { value:false, handler:this.configConstrainToViewport, validator:this.cfg.checkBoolean, supercedes:["iframe","x","y","xy"] } );
-
-	/**
-	* True if the Overlay should have an IFRAME shim (for correcting the select z-index bug in IE6 and below).
-	* @config iframe
-	* @type Boolean
-	* @default true for IE6 and below, false for all others
-	*/
-	this.cfg.addProperty("iframe", { value:(this.browser == "ie" ? true : false), handler:this.configIframe, validator:this.cfg.checkBoolean, supercedes:["zIndex"] } );
-};
-
-/**
-* Moves the Overlay to the specified position. This function is identical to calling this.cfg.setProperty("xy", [x,y]);
-* @method moveTo
-* @param {Number}	x	The Overlay's new x position
-* @param {Number}	y	The Overlay's new y position
-*/
-YAHOO.widget.Overlay.prototype.moveTo = function(x, y) {
-	this.cfg.setProperty("xy",[x,y]);
-};
-
-/**
-* Adds a special CSS class to the Overlay when Mac/Gecko is in use, to work around a Gecko bug where
-* scrollbars cannot be hidden. See https://bugzilla.mozilla.org/show_bug.cgi?id=187435
-* @method hideMacGeckoScrollbars
-*/
-YAHOO.widget.Overlay.prototype.hideMacGeckoScrollbars = function() {
-	YAHOO.util.Dom.removeClass(this.element, "show-scrollbars");
-	YAHOO.util.Dom.addClass(this.element, "hide-scrollbars");
-};
-
-/**
-* Removes a special CSS class from the Overlay when Mac/Gecko is in use, to work around a Gecko bug where
-* scrollbars cannot be hidden. See https://bugzilla.mozilla.org/show_bug.cgi?id=187435
-* @method showMacGeckoScrollbars
-*/
-YAHOO.widget.Overlay.prototype.showMacGeckoScrollbars = function() {
-	YAHOO.util.Dom.removeClass(this.element, "hide-scrollbars");
-	YAHOO.util.Dom.addClass(this.element, "show-scrollbars");
-};
-
-// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* The default event handler fired when the "visible" property is changed. This method is responsible for firing showEvent and hideEvent.
-* @method configVisible
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configVisible = function(type, args, obj) {
-	var visible = args[0];
-
-	var currentVis = YAHOO.util.Dom.getStyle(this.element, "visibility");
-
-	if (currentVis == "inherit") {
-		var e = this.element.parentNode;
-		while (e.nodeType != 9 && e.nodeType != 11) {
-			currentVis = YAHOO.util.Dom.getStyle(e, "visibility");
-			if (currentVis != "inherit") { break; }
-			e = e.parentNode;
-		}
-		if (currentVis == "inherit") {
-			currentVis = "visible";
-		}
-	}
-
-	var effect = this.cfg.getProperty("effect");
-
-	var effectInstances = [];
-	if (effect) {
-		if (effect instanceof Array) {
-			for (var i=0;i<effect.length;i++) {
-				var eff = effect[i];
-				effectInstances[effectInstances.length] = eff.effect(this, eff.duration);
-			}
-		} else {
-			effectInstances[effectInstances.length] = effect.effect(this, effect.duration);
-		}
-	}
-
-	var isMacGecko = (this.platform == "mac" && this.browser == "gecko");
-
-	if (visible) { // Show
-		if (isMacGecko) {
-			this.showMacGeckoScrollbars();
-		}
-
-		if (effect) { // Animate in
-			if (visible) { // Animate in if not showing
-				if (currentVis != "visible" || currentVis === "") {
-					this.beforeShowEvent.fire();
-					for (var j=0;j<effectInstances.length;j++) {
-						var ei = effectInstances[j];
-						if (j === 0 && ! YAHOO.util.Config.alreadySubscribed(ei.animateInCompleteEvent,this.showEvent.fire,this.showEvent)) {
-							ei.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true); // Delegate showEvent until end of animateInComplete
-						}
-						ei.animateIn();
-					}
-				}
-			}
-		} else { // Show
-			if (currentVis != "visible" || currentVis === "") {
-				this.beforeShowEvent.fire();
-				YAHOO.util.Dom.setStyle(this.element, "visibility", "visible");
-				this.cfg.refireEvent("iframe");
-				this.showEvent.fire();
-			}
-		}
-
-	} else { // Hide
-		if (isMacGecko) {
-			this.hideMacGeckoScrollbars();
-		}
-
-		if (effect) { // Animate out if showing
-			if (currentVis == "visible") {
-				this.beforeHideEvent.fire();
-				for (var k=0;k<effectInstances.length;k++) {
-					var h = effectInstances[k];
-					if (k === 0 && ! YAHOO.util.Config.alreadySubscribed(h.animateOutCompleteEvent,this.hideEvent.fire,this.hideEvent)) {
-						h.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true); // Delegate hideEvent until end of animateOutComplete
-					}
-					h.animateOut();
-				}
-			} else if (currentVis === "") {
-				YAHOO.util.Dom.setStyle(this.element, "visibility", "hidden");
-			}
-		} else { // Simple hide
-			if (currentVis == "visible" || currentVis === "") {
-				this.beforeHideEvent.fire();
-				YAHOO.util.Dom.setStyle(this.element, "visibility", "hidden");
-				this.cfg.refireEvent("iframe");
-				this.hideEvent.fire();
-			}
-		}
-	}
-};
-
-/**
-* Center event handler used for centering on scroll/resize, but only if the Overlay is visible
-* @method doCenterOnDOMEvent
-*/
-YAHOO.widget.Overlay.prototype.doCenterOnDOMEvent = function() {
-	if (this.cfg.getProperty("visible")) {
-		this.center();
-	}
-};
-
-/**
-* The default event handler fired when the "fixedcenter" property is changed.
-* @method configFixedCenter
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configFixedCenter = function(type, args, obj) {
-	var val = args[0];
-
-	if (val) {
-		this.center();
-
-		if (! YAHOO.util.Config.alreadySubscribed(this.beforeShowEvent, this.center, this)) {
-			this.beforeShowEvent.subscribe(this.center, this, true);
-		}
-
-		if (! YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowResizeEvent, this.doCenterOnDOMEvent, this)) {
-			YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.doCenterOnDOMEvent, this, true);
-		}
-
-		if (! YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowScrollEvent, this.doCenterOnDOMEvent, this)) {
-			YAHOO.widget.Overlay.windowScrollEvent.subscribe( this.doCenterOnDOMEvent, this, true);
-		}
-	} else {
-		YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
-		YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
-	}
-};
-
-/**
-* The default event handler fired when the "height" property is changed.
-* @method configHeight
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configHeight = function(type, args, obj) {
-	var height = args[0];
-	var el = this.element;
-	YAHOO.util.Dom.setStyle(el, "height", height);
-	this.cfg.refireEvent("iframe");
-};
-
-/**
-* The default event handler fired when the "width" property is changed.
-* @method configWidth
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configWidth = function(type, args, obj) {
-	var width = args[0];
-	var el = this.element;
-	YAHOO.util.Dom.setStyle(el, "width", width);
-	this.cfg.refireEvent("iframe");
-};
-
-/**
-* The default event handler fired when the "zIndex" property is changed.
-* @method configzIndex
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configzIndex = function(type, args, obj) {
-	var zIndex = args[0];
-
-	var el = this.element;
-
-	if (! zIndex) {
-		zIndex = YAHOO.util.Dom.getStyle(el, "zIndex");
-		if (! zIndex || isNaN(zIndex)) {
-			zIndex = 0;
-		}
-	}
-
-	if (this.iframe) {
-		if (zIndex <= 0) {
-			zIndex = 1;
-		}
-		YAHOO.util.Dom.setStyle(this.iframe, "zIndex", (zIndex-1));
-	}
-
-	YAHOO.util.Dom.setStyle(el, "zIndex", zIndex);
-	this.cfg.setProperty("zIndex", zIndex, true);
-};
-
-/**
-* The default event handler fired when the "xy" property is changed.
-* @method configXY
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configXY = function(type, args, obj) {
-	var pos = args[0];
-	var x = pos[0];
-	var y = pos[1];
-
-	this.cfg.setProperty("x", x);
-	this.cfg.setProperty("y", y);
-
-	this.beforeMoveEvent.fire([x,y]);
-
-	x = this.cfg.getProperty("x");
-	y = this.cfg.getProperty("y");
-
-	this.cfg.refireEvent("iframe");
-	this.moveEvent.fire([x,y]);
-};
-
-/**
-* The default event handler fired when the "x" property is changed.
-* @method configX
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configX = function(type, args, obj) {
-	var x = args[0];
-	var y = this.cfg.getProperty("y");
-
-	this.cfg.setProperty("x", x, true);
-	this.cfg.setProperty("y", y, true);
-
-	this.beforeMoveEvent.fire([x,y]);
-
-	x = this.cfg.getProperty("x");
-	y = this.cfg.getProperty("y");
-
-	YAHOO.util.Dom.setX(this.element, x, true);
-
-	this.cfg.setProperty("xy", [x, y], true);
-
-	this.cfg.refireEvent("iframe");
-	this.moveEvent.fire([x, y]);
-};
-
-/**
-* The default event handler fired when the "y" property is changed.
-* @method configY
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configY = function(type, args, obj) {
-	var x = this.cfg.getProperty("x");
-	var y = args[0];
-
-	this.cfg.setProperty("x", x, true);
-	this.cfg.setProperty("y", y, true);
-
-	this.beforeMoveEvent.fire([x,y]);
-
-	x = this.cfg.getProperty("x");
-	y = this.cfg.getProperty("y");
-
-	YAHOO.util.Dom.setY(this.element, y, true);
-
-	this.cfg.setProperty("xy", [x, y], true);
-
-	this.cfg.refireEvent("iframe");
-	this.moveEvent.fire([x, y]);
-};
-
-/**
-* Shows the iframe shim, if it has been enabled
-* @method showIframe
-*/
-YAHOO.widget.Overlay.prototype.showIframe = function() {
-	if (this.iframe) {
-		this.iframe.style.display = "block";
-	}
-};
-
-/**
-* Hides the iframe shim, if it has been enabled
-* @method hideIframe
-*/
-YAHOO.widget.Overlay.prototype.hideIframe = function() {
-	if (this.iframe) {
-		this.iframe.style.display = "none";
-	}
-};
-
-/**
-* The default event handler fired when the "iframe" property is changed.
-* @method configIframe
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configIframe = function(type, args, obj) {
-
-	var val = args[0];
-
-	if (val) { // IFRAME shim is enabled
-
-		if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, this.showIframe, this)) {
-			this.showEvent.subscribe(this.showIframe, this, true);
-		}
-		if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, this.hideIframe, this)) {
-			this.hideEvent.subscribe(this.hideIframe, this, true);
-		}
-
-		var x = this.cfg.getProperty("x");
-		var y = this.cfg.getProperty("y");
-
-		if (! x || ! y) {
-			this.syncPosition();
-			x = this.cfg.getProperty("x");
-			y = this.cfg.getProperty("y");
-		}
-
-		if (! isNaN(x) && ! isNaN(y)) {
-			if (! this.iframe) {
-				this.iframe = document.createElement("iframe");
-				if (this.isSecure) {
-					this.iframe.src = YAHOO.widget.Overlay.IFRAME_SRC;
-				}
-
-				var parent = this.element.parentNode;
-				if (parent) {
-					parent.appendChild(this.iframe);
-				} else {
-					document.body.appendChild(this.iframe);
-				}
-
-				YAHOO.util.Dom.setStyle(this.iframe, "position", "absolute");
-				YAHOO.util.Dom.setStyle(this.iframe, "border", "none");
-				YAHOO.util.Dom.setStyle(this.iframe, "margin", "0");
-				YAHOO.util.Dom.setStyle(this.iframe, "padding", "0");
-				YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
-				if (this.cfg.getProperty("visible")) {
-					this.showIframe();
-				} else {
-					this.hideIframe();
-				}
-			}
-
-			var iframeDisplay = YAHOO.util.Dom.getStyle(this.iframe, "display");
-
-			if (iframeDisplay == "none") {
-				this.iframe.style.display = "block";
-			}
-
-			YAHOO.util.Dom.setXY(this.iframe, [x,y]);
-
-			var width = this.element.clientWidth;
-			var height = this.element.clientHeight;
-
-			YAHOO.util.Dom.setStyle(this.iframe, "width", (width+2) + "px");
-			YAHOO.util.Dom.setStyle(this.iframe, "height", (height+2) + "px");
-
-			if (iframeDisplay == "none") {
-				this.iframe.style.display = "none";
-			}
-		}
-	} else {
-		if (this.iframe) {
-			this.iframe.style.display = "none";
-		}
-		this.showEvent.unsubscribe(this.showIframe, this);
-		this.hideEvent.unsubscribe(this.hideIframe, this);
-	}
-};
-
-
-/**
-* The default event handler fired when the "constraintoviewport" property is changed.
-* @method configConstrainToViewport
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configConstrainToViewport = function(type, args, obj) {
-	var val = args[0];
-	if (val) {
-		if (! YAHOO.util.Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
-			this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
-		}
-	} else {
-		this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
-	}
-};
-
-/**
-* The default event handler fired when the "context" property is changed.
-* @method configContext
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.configContext = function(type, args, obj) {
-	var contextArgs = args[0];
-
-	if (contextArgs) {
-		var contextEl = contextArgs[0];
-		var elementMagnetCorner = contextArgs[1];
-		var contextMagnetCorner = contextArgs[2];
-
-		if (contextEl) {
-			if (typeof contextEl == "string") {
-				this.cfg.setProperty("context", [document.getElementById(contextEl),elementMagnetCorner,contextMagnetCorner], true);
-			}
-
-			if (elementMagnetCorner && contextMagnetCorner) {
-				this.align(elementMagnetCorner, contextMagnetCorner);
-			}
-		}
-	}
-};
-
-
-// END BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* Aligns the Overlay to its context element using the specified corner points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, and BOTTOM_RIGHT.
-* @method align
-* @param {String} elementAlign		The String representing the corner of the Overlay that should be aligned to the context element
-* @param {String} contextAlign		The corner of the context element that the elementAlign corner should stick to.
-*/
-YAHOO.widget.Overlay.prototype.align = function(elementAlign, contextAlign) {
-	var contextArgs = this.cfg.getProperty("context");
-	if (contextArgs) {
-		var context = contextArgs[0];
-
-		var element = this.element;
-		var me = this;
-
-		if (! elementAlign) {
-			elementAlign = contextArgs[1];
-		}
-
-		if (! contextAlign) {
-			contextAlign = contextArgs[2];
-		}
-
-		if (element && context) {
-			var elementRegion = YAHOO.util.Dom.getRegion(element);
-			var contextRegion = YAHOO.util.Dom.getRegion(context);
-
-			var doAlign = function(v,h) {
-				switch (elementAlign) {
-					case YAHOO.widget.Overlay.TOP_LEFT:
-						me.moveTo(h,v);
-						break;
-					case YAHOO.widget.Overlay.TOP_RIGHT:
-						me.moveTo(h-element.offsetWidth,v);
-						break;
-					case YAHOO.widget.Overlay.BOTTOM_LEFT:
-						me.moveTo(h,v-element.offsetHeight);
-						break;
-					case YAHOO.widget.Overlay.BOTTOM_RIGHT:
-						me.moveTo(h-element.offsetWidth,v-element.offsetHeight);
-						break;
-				}
-			};
-
-			switch (contextAlign) {
-				case YAHOO.widget.Overlay.TOP_LEFT:
-					doAlign(contextRegion.top, contextRegion.left);
-					break;
-				case YAHOO.widget.Overlay.TOP_RIGHT:
-					doAlign(contextRegion.top, contextRegion.right);
-					break;
-				case YAHOO.widget.Overlay.BOTTOM_LEFT:
-					doAlign(contextRegion.bottom, contextRegion.left);
-					break;
-				case YAHOO.widget.Overlay.BOTTOM_RIGHT:
-					doAlign(contextRegion.bottom, contextRegion.right);
-					break;
-			}
-		}
-	}
-};
-
-/**
-* The default event handler executed when the moveEvent is fired, if the "constraintoviewport" is set to true.
-* @method enforceConstraints
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Overlay.prototype.enforceConstraints = function(type, args, obj) {
-	var pos = args[0];
-
-	var x = pos[0];
-	var y = pos[1];
-
-	var offsetHeight = this.element.offsetHeight;
-	var offsetWidth = this.element.offsetWidth;
-
-	var viewPortWidth = YAHOO.util.Dom.getViewportWidth();
-	var viewPortHeight = YAHOO.util.Dom.getViewportHeight();
-
-	var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
-	var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
-
-	var topConstraint = scrollY + 10;
-	var leftConstraint = scrollX + 10;
-	var bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10;
-	var rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;
-
-	if (x < leftConstraint) {
-		x = leftConstraint;
-	} else if (x > rightConstraint) {
-		x = rightConstraint;
-	}
-
-	if (y < topConstraint) {
-		y = topConstraint;
-	} else if (y > bottomConstraint) {
-		y = bottomConstraint;
-	}
-
-	this.cfg.setProperty("x", x, true);
-	this.cfg.setProperty("y", y, true);
-	this.cfg.setProperty("xy", [x,y], true);
-};
-
-/**
-* Centers the container in the viewport.
-* @method center
-*/
-YAHOO.widget.Overlay.prototype.center = function() {
-	var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
-	var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
-
-	var viewPortWidth = YAHOO.util.Dom.getClientWidth();
-	var viewPortHeight = YAHOO.util.Dom.getClientHeight();
-
-	var elementWidth = this.element.offsetWidth;
-	var elementHeight = this.element.offsetHeight;
-
-	var x = (viewPortWidth / 2) - (elementWidth / 2) + scrollX;
-	var y = (viewPortHeight / 2) - (elementHeight / 2) + scrollY;
-
-	this.cfg.setProperty("xy", [parseInt(x, 10), parseInt(y, 10)]);
-
-	this.cfg.refireEvent("iframe");
-};
-
-/**
-* Synchronizes the Panel's "xy", "x", and "y" properties with the Panel's position in the DOM. This is primarily used to update position information during drag & drop.
-* @method syncPosition
-*/
-YAHOO.widget.Overlay.prototype.syncPosition = function() {
-	var pos = YAHOO.util.Dom.getXY(this.element);
-	this.cfg.setProperty("x", pos[0], true);
-	this.cfg.setProperty("y", pos[1], true);
-	this.cfg.setProperty("xy", pos, true);
-};
-
-/**
-* Event handler fired when the resize monitor element is resized.
-* @method onDomResize
-* @param {DOMEvent} e	The resize DOM event
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.Overlay.prototype.onDomResize = function(e, obj) {
-	YAHOO.widget.Overlay.superclass.onDomResize.call(this, e, obj);
-	var me = this;
-	setTimeout(function() {
-		me.syncPosition();
-		me.cfg.refireEvent("iframe");
-		me.cfg.refireEvent("context");
-	}, 0);
-};
-
-/**
-* Removes the Overlay element from the DOM and sets all child elements to null.
-* @method destroy
-*/
-YAHOO.widget.Overlay.prototype.destroy = function() {
-	if (this.iframe) {
-		this.iframe.parentNode.removeChild(this.iframe);
-	}
-
-	this.iframe = null;
-
-	YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
-	YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
-
-	YAHOO.widget.Overlay.superclass.destroy.call(this);
-};
-
-/**
-* Returns a String representation of the object.
-* @method toString
-* @return {String} The string representation of the Overlay.
-*/
-YAHOO.widget.Overlay.prototype.toString = function() {
-	return "Overlay " + this.id;
-};
-
-/**
-* A singleton CustomEvent used for reacting to the DOM event for window scroll
-* @event YAHOO.widget.Overlay.windowScrollEvent
-*/
-YAHOO.widget.Overlay.windowScrollEvent = new YAHOO.util.CustomEvent("windowScroll");
-
-/**
-* A singleton CustomEvent used for reacting to the DOM event for window resize
-* @event YAHOO.widget.Overlay.windowResizeEvent
-*/
-YAHOO.widget.Overlay.windowResizeEvent = new YAHOO.util.CustomEvent("windowResize");
-
-/**
-* The DOM event handler used to fire the CustomEvent for window scroll
-* @method YAHOO.widget.Overlay.windowScrollHandler
-* @static
-* @param {DOMEvent} e The DOM scroll event
-*/
-YAHOO.widget.Overlay.windowScrollHandler = function(e) {
-	if (YAHOO.widget.Module.prototype.browser == "ie" || YAHOO.widget.Module.prototype.browser == "ie7") {
-		if (! window.scrollEnd) {
-			window.scrollEnd = -1;
-		}
-		clearTimeout(window.scrollEnd);
-		window.scrollEnd = setTimeout(function() { YAHOO.widget.Overlay.windowScrollEvent.fire(); }, 1);
-	} else {
-		YAHOO.widget.Overlay.windowScrollEvent.fire();
-	}
-};
-
-/**
-* The DOM event handler used to fire the CustomEvent for window resize
-* @method YAHOO.widget.Overlay.windowResizeHandler
-* @static
-* @param {DOMEvent} e The DOM resize event
-*/
-YAHOO.widget.Overlay.windowResizeHandler = function(e) {
-	if (YAHOO.widget.Module.prototype.browser == "ie" || YAHOO.widget.Module.prototype.browser == "ie7") {
-		if (! window.resizeEnd) {
-			window.resizeEnd = -1;
-		}
-		clearTimeout(window.resizeEnd);
-		window.resizeEnd = setTimeout(function() { YAHOO.widget.Overlay.windowResizeEvent.fire(); }, 100);
-	} else {
-		YAHOO.widget.Overlay.windowResizeEvent.fire();
-	}
-};
-
-/**
-* A boolean that indicated whether the window resize and scroll events have already been subscribed to.
-* @property YAHOO.widget.Overlay._initialized
-* @private
-* @type Boolean
-*/
-YAHOO.widget.Overlay._initialized = null;
-
-if (YAHOO.widget.Overlay._initialized === null) {
-	YAHOO.util.Event.addListener(window, "scroll", YAHOO.widget.Overlay.windowScrollHandler);
-	YAHOO.util.Event.addListener(window, "resize", YAHOO.widget.Overlay.windowResizeHandler);
-
-	YAHOO.widget.Overlay._initialized = true;
-}
-
-/**
-* OverlayManager is used for maintaining the focus status of multiple Overlays.* @namespace YAHOO.widget
-* @namespace YAHOO.widget
-* @class OverlayManager
-* @constructor
-* @param {Array}	overlays	Optional. A collection of Overlays to register with the manager.
-* @param {Object}	userConfig		The object literal representing the user configuration of the OverlayManager
-*/
-YAHOO.widget.OverlayManager = function(userConfig) {
-	this.init(userConfig);
-};
-
-/**
-* The CSS class representing a focused Overlay
-* @property YAHOO.widget.OverlayManager.CSS_FOCUSED
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.OverlayManager.CSS_FOCUSED = "focused";
-
-YAHOO.widget.OverlayManager.prototype = {
-	/**
-	* The class's constructor function
-	* @property contructor
-	* @type Function
-	*/
-	constructor : YAHOO.widget.OverlayManager,
-
-	/**
-	* The array of Overlays that are currently registered
-	* @property overlays
-	* @type YAHOO.widget.Overlay[]
-	*/
-	overlays : null,
-
-	/**
-	* Initializes the default configuration of the OverlayManager
-	* @method initDefaultConfig
-	*/
-	initDefaultConfig : function() {
-		/**
-		* The collection of registered Overlays in use by the OverlayManager
-		* @config overlays
-		* @type YAHOO.widget.Overlay[]
-		* @default null
-		*/
-		this.cfg.addProperty("overlays", { suppressEvent:true } );
-
-		/**
-		* The default DOM event that should be used to focus an Overlay
-		* @config focusevent
-		* @type String
-		* @default "mousedown"
-		*/
-		this.cfg.addProperty("focusevent", { value:"mousedown" } );
-	},
-
-	/**
-	* Initializes the OverlayManager
-	* @method init
-	* @param {YAHOO.widget.Overlay[]}	overlays	Optional. A collection of Overlays to register with the manager.
-	* @param {Object}	userConfig		The object literal representing the user configuration of the OverlayManager
-	*/
-	init : function(userConfig) {
-		/**
-		* The OverlayManager's Config object used for monitoring configuration properties.
-		* @property cfg
-		* @type YAHOO.util.Config
-		*/
-		this.cfg = new YAHOO.util.Config(this);
-
-		this.initDefaultConfig();
-
-		if (userConfig) {
-			this.cfg.applyConfig(userConfig, true);
-		}
-		this.cfg.fireQueue();
-
-		/**
-		* The currently activated Overlay
-		* @property activeOverlay
-		* @private
-		* @type YAHOO.widget.Overlay
-		*/
-		var activeOverlay = null;
-
-		/**
-		* Returns the currently focused Overlay
-		* @method getActive
-		* @return {YAHOO.widget.Overlay}	The currently focused Overlay
-		*/
-		this.getActive = function() {
-			return activeOverlay;
-		};
-
-		/**
-		* Focuses the specified Overlay
-		* @method focus
-		* @param {YAHOO.widget.Overlay} overlay	The Overlay to focus
-		* @param {String} overlay	The id of the Overlay to focus
-		*/
-		this.focus = function(overlay) {
-			var o = this.find(overlay);
-			if (o) {
-				this.blurAll();
-				activeOverlay = o;
-				YAHOO.util.Dom.addClass(activeOverlay.element, YAHOO.widget.OverlayManager.CSS_FOCUSED);
-				this.overlays.sort(this.compareZIndexDesc);
-				var topZIndex = YAHOO.util.Dom.getStyle(this.overlays[0].element, "zIndex");
-				if (! isNaN(topZIndex) && this.overlays[0] != overlay) {
-					activeOverlay.cfg.setProperty("zIndex", (parseInt(topZIndex, 10) + 2));
-				}
-				this.overlays.sort(this.compareZIndexDesc);
-			}
-		};
-
-		/**
-		* Removes the specified Overlay from the manager
-		* @method remove
-		* @param {YAHOO.widget.Overlay}	overlay	The Overlay to remove
-		* @param {String} overlay	The id of the Overlay to remove
-		*/
-		this.remove = function(overlay) {
-			var o = this.find(overlay);
-			if (o) {
-				var originalZ = YAHOO.util.Dom.getStyle(o.element, "zIndex");
-				o.cfg.setProperty("zIndex", -1000, true);
-				this.overlays.sort(this.compareZIndexDesc);
-				this.overlays = this.overlays.slice(0, this.overlays.length-1);
-				o.cfg.setProperty("zIndex", originalZ, true);
-
-				o.cfg.setProperty("manager", null);
-				o.focusEvent = null;
-				o.blurEvent = null;
-				o.focus = null;
-				o.blur = null;
-			}
-		};
-
-		/**
-		* Removes focus from all registered Overlays in the manager
-		* @method blurAll
-		*/
-		this.blurAll = function() {
-			activeOverlay = null;
-			for (var o=0;o<this.overlays.length;o++) {
-				YAHOO.util.Dom.removeClass(this.overlays[o].element, YAHOO.widget.OverlayManager.CSS_FOCUSED);
-			}
-		};
-
-		var overlays = this.cfg.getProperty("overlays");
-
-		if (! this.overlays) {
-			this.overlays = [];
-		}
-
-		if (overlays) {
-			this.register(overlays);
-			this.overlays.sort(this.compareZIndexDesc);
-		}
-	},
-
-	/**
-	* Registers an Overlay or an array of Overlays with the manager. Upon registration, the Overlay receives functions for focus and blur, along with CustomEvents for each.
-	* @method register
-	* @param {YAHOO.widget.Overlay}	overlay		An Overlay to register with the manager.
-	* @param {YAHOO.widget.Overlay[]}	overlay		An array of Overlays to register with the manager.
-	* @return	{Boolean}	True if any Overlays are registered.
-	*/
-	register : function(overlay) {
-		if (overlay instanceof YAHOO.widget.Overlay) {
-			overlay.cfg.addProperty("manager", { value:this } );
-
-			overlay.focusEvent = new YAHOO.util.CustomEvent("focus");
-			overlay.blurEvent = new YAHOO.util.CustomEvent("blur");
-
-			var mgr=this;
-
-			overlay.focus = function() {
-				mgr.focus(this);
-				this.focusEvent.fire();
-			};
-
-			overlay.blur = function() {
-				mgr.blurAll();
-				this.blurEvent.fire();
-			};
-
-			var focusOnDomEvent = function(e,obj) {
-				overlay.focus();
-			};
-
-			var focusevent = this.cfg.getProperty("focusevent");
-			YAHOO.util.Event.addListener(overlay.element,focusevent,focusOnDomEvent,this,true);
-
-			var zIndex = YAHOO.util.Dom.getStyle(overlay.element, "zIndex");
-			if (! isNaN(zIndex)) {
-				overlay.cfg.setProperty("zIndex", parseInt(zIndex, 10));
-			} else {
-				overlay.cfg.setProperty("zIndex", 0);
-			}
-
-			this.overlays.push(overlay);
-			return true;
-		} else if (overlay instanceof Array) {
-			var regcount = 0;
-			for (var i=0;i<overlay.length;i++) {
-				if (this.register(overlay[i])) {
-					regcount++;
-				}
-			}
-			if (regcount > 0) {
-				return true;
-			}
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	* Attempts to locate an Overlay by instance or ID.
-	* @method find
-	* @param {YAHOO.widget.Overlay}	overlay		An Overlay to locate within the manager
-	* @param {String}	overlay		An Overlay id to locate within the manager
-	* @return	{YAHOO.widget.Overlay}	The requested Overlay, if found, or null if it cannot be located.
-	*/
-	find : function(overlay) {
-		if (overlay instanceof YAHOO.widget.Overlay) {
-			for (var o=0;o<this.overlays.length;o++) {
-				if (this.overlays[o] == overlay) {
-					return this.overlays[o];
-				}
-			}
-		} else if (typeof overlay == "string") {
-			for (var p=0;p<this.overlays.length;p++) {
-				if (this.overlays[p].id == overlay) {
-					return this.overlays[p];
-				}
-			}
-		}
-		return null;
-	},
-
-	/**
-	* Used for sorting the manager's Overlays by z-index.
-	* @method compareZIndexDesc
-	* @private
-	* @return {Number}	0, 1, or -1, depending on where the Overlay should fall in the stacking order.
-	*/
-	compareZIndexDesc : function(o1, o2) {
-		var zIndex1 = o1.cfg.getProperty("zIndex");
-		var zIndex2 = o2.cfg.getProperty("zIndex");
-
-		if (zIndex1 > zIndex2) {
-			return -1;
-		} else if (zIndex1 < zIndex2) {
-			return 1;
-		} else {
-			return 0;
-		}
-	},
-
-	/**
-	* Shows all Overlays in the manager.
-	* @method showAll
-	*/
-	showAll : function() {
-		for (var o=0;o<this.overlays.length;o++) {
-			this.overlays[o].show();
-		}
-	},
-
-	/**
-	* Hides all Overlays in the manager.
-	* @method hideAll
-	*/
-	hideAll : function() {
-		for (var o=0;o<this.overlays.length;o++) {
-			this.overlays[o].hide();
-		}
-	},
-
-
-	/**
-	* Returns a string representation of the object.
-	* @method toString
-	* @return {String}	The string representation of the OverlayManager
-	*/
-	toString : function() {
-		return "OverlayManager";
-	}
-
-};
-
-/**
-* KeyListener is a utility that provides an easy interface for listening for keydown/keyup events fired against DOM elements.
-* @namespace YAHOO.util
-* @class KeyListener
-* @constructor
-* @param {HTMLElement}	attachTo	The element or element ID to which the key event should be attached
-* @param {String}	attachTo	The element or element ID to which the key event should be attached
-* @param {Object}	keyData		The object literal representing the key(s) to detect. Possible attributes are shift(boolean), alt(boolean), ctrl(boolean) and keys(either an int or an array of ints representing keycodes).
-* @param {Function}	handler		The CustomEvent handler to fire when the key event is detected
-* @param {Object}	handler		An object literal representing the handler.
-* @param {String}	event		Optional. The event (keydown or keyup) to listen for. Defaults automatically to keydown.
-*/
-YAHOO.util.KeyListener = function(attachTo, keyData, handler, event) {
-	if (! event) {
-		event = YAHOO.util.KeyListener.KEYDOWN;
-	}
-
-	/**
-	* The CustomEvent fired internally when a key is pressed
-	* @event keyEvent
-	* @private
-	* @param {Object}	keyData		The object literal representing the key(s) to detect. Possible attributes are shift(boolean), alt(boolean), ctrl(boolean) and keys(either an int or an array of ints representing keycodes).
-	*/
-	var keyEvent = new YAHOO.util.CustomEvent("keyPressed");
-
-	/**
-	* The CustomEvent fired when the KeyListener is enabled via the enable() function
-	* @event enabledEvent
-	* @param {Object}	keyData		The object literal representing the key(s) to detect. Possible attributes are shift(boolean), alt(boolean), ctrl(boolean) and keys(either an int or an array of ints representing keycodes).
-	*/
-	this.enabledEvent = new YAHOO.util.CustomEvent("enabled");
-
-	/**
-	* The CustomEvent fired when the KeyListener is disabled via the disable() function
-	* @event disabledEvent
-	* @param {Object}	keyData		The object literal representing the key(s) to detect. Possible attributes are shift(boolean), alt(boolean), ctrl(boolean) and keys(either an int or an array of ints representing keycodes).
-	*/
-	this.disabledEvent = new YAHOO.util.CustomEvent("disabled");
-
-	if (typeof attachTo == 'string') {
-		attachTo = document.getElementById(attachTo);
-	}
-
-	if (typeof handler == 'function') {
-		keyEvent.subscribe(handler);
-	} else {
-		keyEvent.subscribe(handler.fn, handler.scope, handler.correctScope);
-	}
-
-	/**
-	* Handles the key event when a key is pressed.
-	* @method handleKeyPress
-	* @param {DOMEvent} e	The keypress DOM event
-	* @param {Object}	obj	The DOM event scope object
-	* @private
-	*/
-	function handleKeyPress(e, obj) {
-		if (! keyData.shift) {
-			keyData.shift = false;
-		}
-		if (! keyData.alt) {
-			keyData.alt = false;
-		}
-		if (! keyData.ctrl) {
-			keyData.ctrl = false;
-		}
-
-		// check held down modifying keys first
-		if (e.shiftKey == keyData.shift &&
-			e.altKey   == keyData.alt &&
-			e.ctrlKey  == keyData.ctrl) { // if we pass this, all modifiers match
-
-			var dataItem;
-			var keyPressed;
-
-			if (keyData.keys instanceof Array) {
-				for (var i=0;i<keyData.keys.length;i++) {
-					dataItem = keyData.keys[i];
-
-					if (dataItem == e.charCode ) {
-						keyEvent.fire(e.charCode, e);
-						break;
-					} else if (dataItem == e.keyCode) {
-						keyEvent.fire(e.keyCode, e);
-						break;
-					}
-				}
-			} else {
-				dataItem = keyData.keys;
-
-				if (dataItem == e.charCode ) {
-					keyEvent.fire(e.charCode, e);
-				} else if (dataItem == e.keyCode) {
-					keyEvent.fire(e.keyCode, e);
-				}
-			}
-		}
-	}
-
-	/**
-	* Enables the KeyListener by attaching the DOM event listeners to the target DOM element
-	* @method enable
-	*/
-	this.enable = function() {
-		if (! this.enabled) {
-			YAHOO.util.Event.addListener(attachTo, event, handleKeyPress);
-			this.enabledEvent.fire(keyData);
-		}
-		/**
-		* Boolean indicating the enabled/disabled state of the Tooltip
-		* @property enabled
-		* @type Boolean
-		*/
-		this.enabled = true;
-	};
-
-	/**
-	* Disables the KeyListener by removing the DOM event listeners from the target DOM element
-	* @method disable
-	*/
-	this.disable = function() {
-		if (this.enabled) {
-			YAHOO.util.Event.removeListener(attachTo, event, handleKeyPress);
-			this.disabledEvent.fire(keyData);
-		}
-		this.enabled = false;
-	};
-
-	/**
-	* Returns a String representation of the object.
-	* @method toString
-	* @return {String}	The string representation of the KeyListener
-	*/
-	this.toString = function() {
-		return "KeyListener [" + keyData.keys + "] " + attachTo.tagName + (attachTo.id ? "[" + attachTo.id + "]" : "");
-	};
-
-};
-
-/**
-* Constant representing the DOM "keydown" event.
-* @property YAHOO.util.KeyListener.KEYDOWN
-* @static
-* @final
-* @type String
-*/
-YAHOO.util.KeyListener.KEYDOWN = "keydown";
-
-/**
-* Constant representing the DOM "keyup" event.
-* @property YAHOO.util.KeyListener.KEYUP
-* @static
-* @final
-* @type String
-*/
-YAHOO.util.KeyListener.KEYUP = "keyup";
-
-/**
-* Tooltip is an implementation of Overlay that behaves like an OS tooltip, displaying when the user mouses over a particular element, and disappearing on mouse out.
-* @namespace YAHOO.widget
-* @class Tooltip
-* @extends YAHOO.widget.Overlay
-* @constructor
-* @param {String}	el	The element ID representing the Tooltip <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Tooltip
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Overlay. See configuration documentation for more details.
-*/
-YAHOO.widget.Tooltip = function(el, userConfig) {
-	YAHOO.widget.Tooltip.superclass.constructor.call(this, el, userConfig);
-};
-
-YAHOO.extend(YAHOO.widget.Tooltip, YAHOO.widget.Overlay);
-
-/**
-* Constant representing the Tooltip CSS class
-* @property YAHOO.widget.Tooltip.CSS_TOOLTIP
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Tooltip.CSS_TOOLTIP = "tt";
-
-/**
-* The Tooltip initialization method. This method is automatically called by the constructor. A Tooltip is automatically rendered by the init method, and it also is set to be invisible by default, and constrained to viewport by default as well.
-* @method init
-* @param {String}	el	The element ID representing the Tooltip <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Tooltip
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Tooltip. See configuration documentation for more details.
-*/
-YAHOO.widget.Tooltip.prototype.init = function(el, userConfig) {
-	if (document.readyState && document.readyState != "complete") {
-		var deferredInit = function() {
-			this.init(el, userConfig);
-		};
-		YAHOO.util.Event.addListener(window, "load", deferredInit, this, true);
-	} else {
-		YAHOO.widget.Tooltip.superclass.init.call(this, el);
-
-		this.beforeInitEvent.fire(YAHOO.widget.Tooltip);
-
-		YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Tooltip.CSS_TOOLTIP);
-
-		if (userConfig) {
-			this.cfg.applyConfig(userConfig, true);
-		}
-
-		this.cfg.queueProperty("visible",false);
-		this.cfg.queueProperty("constraintoviewport",true);
-
-		this.setBody("");
-		this.render(this.cfg.getProperty("container"));
-
-		this.initEvent.fire(YAHOO.widget.Tooltip);
-	}
-};
-
-/**
-* Initializes the class's configurable properties which can be changed using the Overlay's Config object (cfg).
-* @method initDefaultConfig
-*/
-YAHOO.widget.Tooltip.prototype.initDefaultConfig = function() {
-	YAHOO.widget.Tooltip.superclass.initDefaultConfig.call(this);
-
-	/**
-	* Specifies whether the Tooltip should be kept from overlapping its context element.
-	* @config preventoverlap
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("preventoverlap",		{ value:true, validator:this.cfg.checkBoolean, supercedes:["x","y","xy"] } );
-
-	/**
-	* The number of milliseconds to wait before showing a Tooltip on mouseover.
-	* @config showdelay
-	* @type Number
-	* @default 200
-	*/
-	this.cfg.addProperty("showdelay",			{ value:200, handler:this.configShowDelay, validator:this.cfg.checkNumber } );
-
-	/**
-	* The number of milliseconds to wait before automatically dismissing a Tooltip after the mouse has been resting on the context element.
-	* @config autodismissdelay
-	* @type Number
-	* @default 5000
-	*/
-	this.cfg.addProperty("autodismissdelay",	{ value:5000, handler:this.configAutoDismissDelay, validator:this.cfg.checkNumber } );
-
-	/**
-	* The number of milliseconds to wait before hiding a Tooltip on mouseover.
-	* @config hidedelay
-	* @type Number
-	* @default 250
-	*/
-	this.cfg.addProperty("hidedelay",			{ value:250, handler:this.configHideDelay, validator:this.cfg.checkNumber } );
-
-	/**
-	* Specifies the Tooltip's text.
-	* @config text
-	* @type String
-	* @default null
-	*/
-	this.cfg.addProperty("text",				{ handler:this.configText, suppressEvent:true } );
-
-	/**
-	* Specifies the container element that the Tooltip's markup should be rendered into.
-	* @config container
-	* @type HTMLElement/String
-	* @default document.body
-	*/
-	this.cfg.addProperty("container",			{ value:document.body, handler:this.configContainer } );
-
-	/**
-	* Specifies the element or elements that the Tooltip should be anchored to on mouseover.
-	* @config context
-	* @type HTMLElement[]/String[]
-	* @default null
-	*/
-
-};
-
-// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* The default event handler fired when the "text" property is changed.
-* @method configText
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Tooltip.prototype.configText = function(type, args, obj) {
-	var text = args[0];
-	if (text) {
-		this.setBody(text);
-	}
-};
-
-/**
-* The default event handler fired when the "container" property is changed.
-* @method configContainer
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Tooltip.prototype.configContainer = function(type, args, obj) {
-	var container = args[0];
-	if (typeof container == 'string') {
-		this.cfg.setProperty("container", document.getElementById(container), true);
-	}
-};
-
-/**
-* The default event handler fired when the "context" property is changed.
-* @method configContext
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Tooltip.prototype.configContext = function(type, args, obj) {
-	var context = args[0];
-	if (context) {
-
-		// Normalize parameter into an array
-		if (! (context instanceof Array)) {
-			if (typeof context == "string") {
-				this.cfg.setProperty("context", [document.getElementById(context)], true);
-			} else { // Assuming this is an element
-				this.cfg.setProperty("context", [context], true);
-			}
-			context = this.cfg.getProperty("context");
-		}
-
-
-		// Remove any existing mouseover/mouseout listeners
-		if (this._context) {
-			for (var c=0;c<this._context.length;++c) {
-				var el = this._context[c];
-				YAHOO.util.Event.removeListener(el, "mouseover", this.onContextMouseOver);
-				YAHOO.util.Event.removeListener(el, "mousemove", this.onContextMouseMove);
-				YAHOO.util.Event.removeListener(el, "mouseout", this.onContextMouseOut);
-			}
-		}
-
-		// Add mouseover/mouseout listeners to context elements
-		this._context = context;
-		for (var d=0;d<this._context.length;++d) {
-			var el2 = this._context[d];
-			YAHOO.util.Event.addListener(el2, "mouseover", this.onContextMouseOver, this);
-			YAHOO.util.Event.addListener(el2, "mousemove", this.onContextMouseMove, this);
-			YAHOO.util.Event.addListener(el2, "mouseout", this.onContextMouseOut, this);
-		}
-	}
-};
-
-// END BUILT-IN PROPERTY EVENT HANDLERS //
-
-// BEGIN BUILT-IN DOM EVENT HANDLERS //
-
-/**
-* The default event handler fired when the user moves the mouse while over the context element.
-* @method onContextMouseMove
-* @param {DOMEvent} e	The current DOM event
-* @param {Object}	obj	The object argument
-*/
-YAHOO.widget.Tooltip.prototype.onContextMouseMove = function(e, obj) {
-	obj.pageX = YAHOO.util.Event.getPageX(e);
-	obj.pageY = YAHOO.util.Event.getPageY(e);
-
-};
-
-/**
-* The default event handler fired when the user mouses over the context element.
-* @method onContextMouseOver
-* @param {DOMEvent} e	The current DOM event
-* @param {Object}	obj	The object argument
-*/
-YAHOO.widget.Tooltip.prototype.onContextMouseOver = function(e, obj) {
-
-	if (obj.hideProcId) {
-		clearTimeout(obj.hideProcId);
-		obj.hideProcId = null;
-	}
-
-	var context = this;
-	YAHOO.util.Event.addListener(context, "mousemove", obj.onContextMouseMove, obj);
-
-	if (context.title) {
-		obj._tempTitle = context.title;
-		context.title = "";
-	}
-
-	/**
-	* The unique process ID associated with the thread responsible for showing the Tooltip.
-	* @type int
-	*/
-	obj.showProcId = obj.doShow(e, context);
-};
-
-/**
-* The default event handler fired when the user mouses out of the context element.
-* @method onContextMouseOut
-* @param {DOMEvent} e	The current DOM event
-* @param {Object}	obj	The object argument
-*/
-YAHOO.widget.Tooltip.prototype.onContextMouseOut = function(e, obj) {
-	var el = this;
-
-	if (obj._tempTitle) {
-		el.title = obj._tempTitle;
-		obj._tempTitle = null;
-	}
-
-	if (obj.showProcId) {
-		clearTimeout(obj.showProcId);
-		obj.showProcId = null;
-	}
-
-	if (obj.hideProcId) {
-		clearTimeout(obj.hideProcId);
-		obj.hideProcId = null;
-	}
-
-
-	obj.hideProcId = setTimeout(function() {
-				obj.hide();
-				}, obj.cfg.getProperty("hidedelay"));
-};
-
-// END BUILT-IN DOM EVENT HANDLERS //
-
-/**
-* Processes the showing of the Tooltip by setting the timeout delay and offset of the Tooltip.
-* @method doShow
-* @param {DOMEvent} e	The current DOM event
-* @return {Number}	The process ID of the timeout function associated with doShow
-*/
-YAHOO.widget.Tooltip.prototype.doShow = function(e, context) {
-
-	var yOffset = 25;
-	if (this.browser == "opera" && context.tagName == "A") {
-		yOffset += 12;
-	}
-
-	var me = this;
-	return setTimeout(
-		function() {
-			if (me._tempTitle) {
-				me.setBody(me._tempTitle);
-			} else {
-				me.cfg.refireEvent("text");
-			}
-
-			me.moveTo(me.pageX, me.pageY + yOffset);
-			if (me.cfg.getProperty("preventoverlap")) {
-				me.preventOverlap(me.pageX, me.pageY);
-			}
-
-			YAHOO.util.Event.removeListener(context, "mousemove", me.onContextMouseMove);
-
-			me.show();
-			me.hideProcId = me.doHide();
-		},
-	this.cfg.getProperty("showdelay"));
-};
-
-/**
-* Sets the timeout for the auto-dismiss delay, which by default is 5 seconds, meaning that a tooltip will automatically dismiss itself after 5 seconds of being displayed.
-* @method doHide
-*/
-YAHOO.widget.Tooltip.prototype.doHide = function() {
-	var me = this;
-	return setTimeout(
-		function() {
-			me.hide();
-		},
-		this.cfg.getProperty("autodismissdelay"));
-};
-
-/**
-* Fired when the Tooltip is moved, this event handler is used to prevent the Tooltip from overlapping with its context element.
-* @method preventOverlay
-* @param {Number} pageX	The x coordinate position of the mouse pointer
-* @param {Number} pageY	The y coordinate position of the mouse pointer
-*/
-YAHOO.widget.Tooltip.prototype.preventOverlap = function(pageX, pageY) {
-
-	var height = this.element.offsetHeight;
-
-	var elementRegion = YAHOO.util.Dom.getRegion(this.element);
-
-	elementRegion.top -= 5;
-	elementRegion.left -= 5;
-	elementRegion.right += 5;
-	elementRegion.bottom += 5;
-
-	var mousePoint = new YAHOO.util.Point(pageX, pageY);
-
-	if (elementRegion.contains(mousePoint)) {
-		this.cfg.setProperty("y", (pageY-height-5));
-	}
-};
-
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String}	The string representation of the Tooltip
-*/
-YAHOO.widget.Tooltip.prototype.toString = function() {
-	return "Tooltip " + this.id;
-};
-
-/**
-* Panel is an implementation of Overlay that behaves like an OS window, with a draggable header and an optional close icon at the top right.
-* @namespace YAHOO.widget
-* @class Panel
-* @extends YAHOO.widget.Overlay
-* @constructor
-* @param {String}	el	The element ID representing the Panel <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Panel
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Panel. See configuration documentation for more details.
-*/
-YAHOO.widget.Panel = function(el, userConfig) {
-	YAHOO.widget.Panel.superclass.constructor.call(this, el, userConfig);
-};
-
-YAHOO.extend(YAHOO.widget.Panel, YAHOO.widget.Overlay);
-
-/**
-* Constant representing the default CSS class used for a Panel
-* @property YAHOO.widget.Panel.CSS_PANEL
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Panel.CSS_PANEL = "panel";
-
-/**
-* Constant representing the default CSS class used for a Panel's wrapping container
-* @property YAHOO.widget.Panel.CSS_PANEL_CONTAINER
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Panel.CSS_PANEL_CONTAINER = "panel-container";
-
-/**
-* The Overlay initialization method, which is executed for Overlay and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
-* @method init
-* @param {String}	el	The element ID representing the Overlay <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Overlay
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Overlay. See configuration documentation for more details.
-*/
-YAHOO.widget.Panel.prototype.init = function(el, userConfig) {
-	YAHOO.widget.Panel.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
-
-	this.beforeInitEvent.fire(YAHOO.widget.Panel);
-
-	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Panel.CSS_PANEL);
-
-	this.buildWrapper();
-
-	if (userConfig) {
-		this.cfg.applyConfig(userConfig, true);
-	}
-
-	this.beforeRenderEvent.subscribe(function() {
-		var draggable = this.cfg.getProperty("draggable");
-		if (draggable) {
-			if (! this.header) {
-				this.setHeader("&#160;");
-			}
-		}
-	}, this, true);
-
-	var me = this;
-
-	var doBlur = function() {
-		this.blur();
-	};
-
-	this.showMaskEvent.subscribe(function() {
-		var checkFocusable = function(el) {
-			if ((el.tagName == "A" || el.tagName == "BUTTON" || el.tagName == "SELECT" || el.tagName == "INPUT" || el.tagName == "TEXTAREA" || el.tagName == "FORM") && el.type != "hidden") {
-				if (! YAHOO.util.Dom.isAncestor(me.element, el)) {
-					YAHOO.util.Event.addListener(el, "focus", doBlur, el, true);
-					return true;
-				}
-			} else {
-				return false;
-			}
-		};
-
-		this.focusableElements = YAHOO.util.Dom.getElementsBy(checkFocusable);
-	}, this, true);
-
-	this.hideMaskEvent.subscribe(function() {
-		for (var i=0;i<this.focusableElements.length;i++) {
-			var el2 = this.focusableElements[i];
-			YAHOO.util.Event.removeListener(el2, "focus", doBlur);
-		}
-	}, this, true);
-
-	this.beforeShowEvent.subscribe(function() {
-		this.cfg.refireEvent("underlay");
-	}, this, true);
-
-	this.initEvent.fire(YAHOO.widget.Panel);
-};
-
-/**
-* Initializes the custom events for Module which are fired automatically at appropriate times by the Module class.
-*/
-YAHOO.widget.Panel.prototype.initEvents = function() {
-	YAHOO.widget.Panel.superclass.initEvents.call(this);
-
-	/**
-	* CustomEvent fired after the modality mask is shown
-	* @event showMaskEvent
-	*/
-	this.showMaskEvent = new YAHOO.util.CustomEvent("showMask");
-
-	/**
-	* CustomEvent fired after the modality mask is hidden
-	* @event hideMaskEvent
-	*/
-	this.hideMaskEvent = new YAHOO.util.CustomEvent("hideMask");
-
-	/**
-	* CustomEvent when the Panel is dragged
-	* @event dragEvent
-	*/
-	this.dragEvent = new YAHOO.util.CustomEvent("drag");
-};
-
-/**
-* Initializes the class's configurable properties which can be changed using the Panel's Config object (cfg).
-* @method initDefaultConfig
-*/
-YAHOO.widget.Panel.prototype.initDefaultConfig = function() {
-	YAHOO.widget.Panel.superclass.initDefaultConfig.call(this);
-
-	// Add panel config properties //
-
-	/**
-	* True if the Panel should display a "close" button
-	* @config close
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("close", { value:true, handler:this.configClose, validator:this.cfg.checkBoolean, supercedes:["visible"] } );
-
-	/**
-	* True if the Panel should be draggable
-	* @config draggable
-	* @type Boolean
-	* @default true
-	*/
-	this.cfg.addProperty("draggable", { value:true,	handler:this.configDraggable, validator:this.cfg.checkBoolean, supercedes:["visible"] } );
-
-	/**
-	* Sets the type of underlay to display for the Panel. Valid values are "shadow", "matte", and "none".
-	* @config underlay
-	* @type String
-	* @default shadow
-	*/
-	this.cfg.addProperty("underlay", { value:"shadow", handler:this.configUnderlay, supercedes:["visible"] } );
-
-	/**
-	* True if the Panel should be displayed in a modal fashion, automatically creating a transparent mask over the document that will not be removed until the Panel is dismissed.
-	* @config modal
-	* @type Boolean
-	* @default false
-	*/
-	this.cfg.addProperty("modal",	{ value:false, handler:this.configModal, validator:this.cfg.checkBoolean, supercedes:["visible"] } );
-
-	/**
-	* A KeyListener (or array of KeyListeners) that will be enabled when the Panel is shown, and disabled when the Panel is hidden.
-	* @config keylisteners
-	* @type YAHOO.util.KeyListener[]
-	* @default null
-	*/
-	this.cfg.addProperty("keylisteners", { handler:this.configKeyListeners, suppressEvent:true, supercedes:["visible"] } );
-};
-
-// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* The default event handler fired when the "close" property is changed. The method controls the appending or hiding of the close icon at the top right of the Panel.
-* @method configClose
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configClose = function(type, args, obj) {
-	var val = args[0];
-
-	var doHide = function(e, obj) {
-		obj.hide();
-	};
-
-	if (val) {
-		if (! this.close) {
-			this.close = document.createElement("DIV");
-			YAHOO.util.Dom.addClass(this.close, "close");
-
-			if (this.isSecure) {
-				YAHOO.util.Dom.addClass(this.close, "secure");
-			} else {
-				YAHOO.util.Dom.addClass(this.close, "nonsecure");
-			}
-
-			this.close.innerHTML = "&#160;";
-			this.innerElement.appendChild(this.close);
-			YAHOO.util.Event.addListener(this.close, "click", doHide, this);
-		} else {
-			this.close.style.display = "block";
-		}
-	} else {
-		if (this.close) {
-			this.close.style.display = "none";
-		}
-	}
-};
-
-/**
-* The default event handler fired when the "draggable" property is changed.
-* @method configDraggable
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configDraggable = function(type, args, obj) {
-	var val = args[0];
-	if (val) {
-		if (this.header) {
-			YAHOO.util.Dom.setStyle(this.header,"cursor","move");
-			this.registerDragDrop();
-		}
-	} else {
-		if (this.dd) {
-			this.dd.unreg();
-		}
-		if (this.header) {
-			YAHOO.util.Dom.setStyle(this.header,"cursor","auto");
-		}
-	}
-};
-
-/**
-* The default event handler fired when the "underlay" property is changed.
-* @method configUnderlay
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configUnderlay = function(type, args, obj) {
-	var val = args[0];
-
-	switch (val.toLowerCase()) {
-		case "shadow":
-			YAHOO.util.Dom.removeClass(this.element, "matte");
-			YAHOO.util.Dom.addClass(this.element, "shadow");
-
-			if (! this.underlay) { // create if not already in DOM
-				this.underlay = document.createElement("DIV");
-				this.underlay.className = "underlay";
-				this.underlay.innerHTML = "&#160;";
-				this.element.appendChild(this.underlay);
-			}
-
-			this.sizeUnderlay();
-			break;
-		case "matte":
-			YAHOO.util.Dom.removeClass(this.element, "shadow");
-			YAHOO.util.Dom.addClass(this.element, "matte");
-			break;
-		default:
-			YAHOO.util.Dom.removeClass(this.element, "shadow");
-			YAHOO.util.Dom.removeClass(this.element, "matte");
-			break;
-	}
-};
-
-/**
-* The default event handler fired when the "modal" property is changed. This handler subscribes or unsubscribes to the show and hide events to handle the display or hide of the modality mask.
-* @method configModal
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configModal = function(type, args, obj) {
-	var modal = args[0];
-
-	if (modal) {
-		this.buildMask();
-
-		if (! YAHOO.util.Config.alreadySubscribed( this.beforeShowEvent, this.showMask, this ) ) {
-			this.beforeShowEvent.subscribe(this.showMask, this, true);
-		}
-		if (! YAHOO.util.Config.alreadySubscribed( this.hideEvent, this.hideMask, this) ) {
-			this.hideEvent.subscribe(this.hideMask, this, true);
-		}
-		if (! YAHOO.util.Config.alreadySubscribed( YAHOO.widget.Overlay.windowResizeEvent, this.sizeMask, this ) ) {
-			YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.sizeMask, this, true);
-		}
-		if (! YAHOO.util.Config.alreadySubscribed( this.destroyEvent, this.removeMask, this) ) {
-			this.destroyEvent.subscribe(this.removeMask, this, true);
-		}
-
-		this.cfg.refireEvent("zIndex");
-	} else {
-		this.beforeShowEvent.unsubscribe(this.showMask, this);
-		this.hideEvent.unsubscribe(this.hideMask, this);
-		YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.sizeMask, this);
-		this.destroyEvent.unsubscribe(this.removeMask, this);
-	}
-};
-
-/**
-* Removes the modality mask.
-* @method removeMask
-*/
-YAHOO.widget.Panel.prototype.removeMask = function() {
-	if (this.mask) {
-		if (this.mask.parentNode) {
-			this.mask.parentNode.removeChild(this.mask);
-		}
-		this.mask = null;
-	}
-};
-
-/**
-* The default event handler fired when the "keylisteners" property is changed.
-* @method configKeyListeners
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configKeyListeners = function(type, args, obj) {
-	var listeners = args[0];
-
-	if (listeners) {
-		if (listeners instanceof Array) {
-			for (var i=0;i<listeners.length;i++) {
-				var listener = listeners[i];
-
-				if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, listener.enable, listener)) {
-					this.showEvent.subscribe(listener.enable, listener, true);
-				}
-				if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, listener.disable, listener)) {
-					this.hideEvent.subscribe(listener.disable, listener, true);
-					this.destroyEvent.subscribe(listener.disable, listener, true);
-				}
-			}
-		} else {
-			if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, listeners.enable, listeners)) {
-				this.showEvent.subscribe(listeners.enable, listeners, true);
-			}
-			if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, listeners.disable, listeners)) {
-				this.hideEvent.subscribe(listeners.disable, listeners, true);
-				this.destroyEvent.subscribe(listeners.disable, listeners, true);
-			}
-		}
-	}
-};
-
-/**
-* The default event handler fired when the "height" property is changed.
-* @method configHeight
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configHeight = function(type, args, obj) {
-	var height = args[0];
-	var el = this.innerElement;
-	YAHOO.util.Dom.setStyle(el, "height", height);
-	this.cfg.refireEvent("underlay");
-	this.cfg.refireEvent("iframe");
-};
-
-/**
-* The default event handler fired when the "width" property is changed.
-* @method configWidth
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configWidth = function(type, args, obj) {
-	var width = args[0];
-	var el = this.innerElement;
-	YAHOO.util.Dom.setStyle(el, "width", width);
-	this.cfg.refireEvent("underlay");
-	this.cfg.refireEvent("iframe");
-};
-
-/**
-* The default event handler fired when the "zIndex" property is changed.
-* @method configzIndex
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Panel.prototype.configzIndex = function(type, args, obj) {
-	YAHOO.widget.Panel.superclass.configzIndex.call(this, type, args, obj);
-
-	var maskZ = 0;
-	var currentZ = YAHOO.util.Dom.getStyle(this.element, "zIndex");
-
-	if (this.mask) {
-		if (! currentZ || isNaN(currentZ)) {
-			currentZ = 0;
-		}
-
-		if (currentZ === 0) {
-			this.cfg.setProperty("zIndex", 1);
-		} else {
-			maskZ = currentZ - 1;
-			YAHOO.util.Dom.setStyle(this.mask, "zIndex", maskZ);
-		}
-
-	}
-};
-
-// END BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* Builds the wrapping container around the Panel that is used for positioning the shadow and matte underlays. The container element is assigned to a  local instance variable called container, and the element is reinserted inside of it.
-* @method buildWrapper
-*/
-YAHOO.widget.Panel.prototype.buildWrapper = function() {
-	var elementParent = this.element.parentNode;
-	var originalElement = this.element;
-
-	var wrapper = document.createElement("DIV");
-	wrapper.className = YAHOO.widget.Panel.CSS_PANEL_CONTAINER;
-	wrapper.id = originalElement.id + "_c";
-
-	if (elementParent) {
-		elementParent.insertBefore(wrapper, originalElement);
-	}
-
-	wrapper.appendChild(originalElement);
-
-	this.element = wrapper;
-	this.innerElement = originalElement;
-
-	YAHOO.util.Dom.setStyle(this.innerElement, "visibility", "inherit");
-};
-
-/**
-* Adjusts the size of the shadow based on the size of the element.
-* @method sizeUnderlay
-*/
-YAHOO.widget.Panel.prototype.sizeUnderlay = function() {
-	if (this.underlay && this.browser != "gecko" && this.browser != "safari") {
-		this.underlay.style.width = this.innerElement.offsetWidth + "px";
-		this.underlay.style.height = this.innerElement.offsetHeight + "px";
-	}
-};
-
-/**
-* Event handler fired when the resize monitor element is resized.
-* @method onDomResize
-* @param {DOMEvent} e	The resize DOM event
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.Panel.prototype.onDomResize = function(e, obj) {
-	YAHOO.widget.Panel.superclass.onDomResize.call(this, e, obj);
-	var me = this;
-	setTimeout(function() {
-		me.sizeUnderlay();
-	}, 0);
-};
-
-/**
-* Registers the Panel's header for drag & drop capability.
-* @method registerDragDrop
-*/
-YAHOO.widget.Panel.prototype.registerDragDrop = function() {
-	if (this.header) {
-		this.dd = new YAHOO.util.DD(this.element.id, this.id);
-
-		if (! this.header.id) {
-			this.header.id = this.id + "_h";
-		}
-
-		var me = this;
-
-		this.dd.startDrag = function() {
-
-			if (me.browser == "ie") {
-				YAHOO.util.Dom.addClass(me.element,"drag");
-			}
-
-			if (me.cfg.getProperty("constraintoviewport")) {
-				var offsetHeight = me.element.offsetHeight;
-				var offsetWidth = me.element.offsetWidth;
-
-				var viewPortWidth = YAHOO.util.Dom.getViewportWidth();
-				var viewPortHeight = YAHOO.util.Dom.getViewportHeight();
-
-				var scrollX = window.scrollX || document.documentElement.scrollLeft;
-				var scrollY = window.scrollY || document.documentElement.scrollTop;
-
-				var topConstraint = scrollY + 10;
-				var leftConstraint = scrollX + 10;
-				var bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10;
-				var rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;
-
-				this.minX = leftConstraint;
-				this.maxX = rightConstraint;
-				this.constrainX = true;
-
-				this.minY = topConstraint;
-				this.maxY = bottomConstraint;
-				this.constrainY = true;
-			} else {
-				this.constrainX = false;
-				this.constrainY = false;
-			}
-
-			me.dragEvent.fire("startDrag", arguments);
-		};
-
-		this.dd.onDrag = function() {
-			me.syncPosition();
-			me.cfg.refireEvent("iframe");
-			if (this.platform == "mac" && this.browser == "gecko") {
-				this.showMacGeckoScrollbars();
-			}
-
-			me.dragEvent.fire("onDrag", arguments);
-		};
-
-		this.dd.endDrag = function() {
-			if (me.browser == "ie") {
-				YAHOO.util.Dom.removeClass(me.element,"drag");
-			}
-
-			me.dragEvent.fire("endDrag", arguments);
-		};
-
-		this.dd.setHandleElId(this.header.id);
-		this.dd.addInvalidHandleType("INPUT");
-		this.dd.addInvalidHandleType("SELECT");
-		this.dd.addInvalidHandleType("TEXTAREA");
-	}
-};
-
-/**
-* Builds the mask that is laid over the document when the Panel is configured to be modal.
-* @method buildMask
-*/
-YAHOO.widget.Panel.prototype.buildMask = function() {
-	if (! this.mask) {
-		this.mask = document.createElement("DIV");
-		this.mask.id = this.id + "_mask";
-		this.mask.className = "mask";
-		this.mask.innerHTML = "&#160;";
-
-		var maskClick = function(e, obj) {
-			YAHOO.util.Event.stopEvent(e);
-		};
-
-		var firstChild = document.body.firstChild;
-		if (firstChild)	{
-			document.body.insertBefore(this.mask, document.body.firstChild);
-		} else {
-			document.body.appendChild(this.mask);
-		}
-	}
-};
-
-/**
-* Hides the modality mask.
-* @method hideMask
-*/
-YAHOO.widget.Panel.prototype.hideMask = function() {
-	if (this.cfg.getProperty("modal") && this.mask) {
-		this.mask.style.display = "none";
-		this.hideMaskEvent.fire();
-		YAHOO.util.Dom.removeClass(document.body, "masked");
-	}
-};
-
-/**
-* Shows the modality mask.
-* @method showMask
-*/
-YAHOO.widget.Panel.prototype.showMask = function() {
-	if (this.cfg.getProperty("modal") && this.mask) {
-		YAHOO.util.Dom.addClass(document.body, "masked");
-		this.sizeMask();
-		this.mask.style.display = "block";
-		this.showMaskEvent.fire();
-	}
-};
-
-/**
-* Sets the size of the modality mask to cover the entire scrollable area of the document
-* @method sizeMask
-*/
-YAHOO.widget.Panel.prototype.sizeMask = function() {
-	if (this.mask) {
-		this.mask.style.height = YAHOO.util.Dom.getDocumentHeight()+"px";
-		this.mask.style.width = YAHOO.util.Dom.getDocumentWidth()+"px";
-	}
-};
-
-/**
-* Renders the Panel by inserting the elements that are not already in the main Panel into their correct places. Optionally appends the Panel to the specified node prior to the render's execution. NOTE: For Panels without existing markup, the appendToNode argument is REQUIRED. If this argument is ommitted and the current element is not present in the document, the function will return false, indicating that the render was a failure.
-* @method render
-* @param {String}	appendToNode	The element id to which the Module should be appended to prior to rendering <em>OR</em>
-* @param {HTMLElement}	appendToNode	The element to which the Module should be appended to prior to rendering
-* @return {boolean} Success or failure of the render
-*/
-YAHOO.widget.Panel.prototype.render = function(appendToNode) {
-	return YAHOO.widget.Panel.superclass.render.call(this, appendToNode, this.innerElement);
-};
-
-/**
-* Returns a String representation of the object.
-* @method toString
-* @return {String} The string representation of the Panel.
-*/
-YAHOO.widget.Panel.prototype.toString = function() {
-	return "Panel " + this.id;
-};
-
-/**
-* Dialog is an implementation of Panel that can be used to submit form data. Built-in functionality for buttons with event handlers is included, and button sets can be build dynamically, or the preincluded ones for Submit/Cancel and OK/Cancel can be utilized. Forms can be processed in 3 ways -- via an asynchronous Connection utility call, a simple form POST or GET, or manually.
-* @namespace YAHOO.widget
-* @class Dialog
-* @extends YAHOO.widget.Panel
-* @constructor
-* @param {String}	el	The element ID representing the Dialog <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Dialog
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Dialog. See configuration documentation for more details.
-*/
-YAHOO.widget.Dialog = function(el, userConfig) {
-	YAHOO.widget.Dialog.superclass.constructor.call(this, el, userConfig);
-};
-
-YAHOO.extend(YAHOO.widget.Dialog, YAHOO.widget.Panel);
-
-/**
-* Constant representing the default CSS class used for a Dialog
-* @property YAHOO.widget.Dialog.CSS_DIALOG
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.Dialog.CSS_DIALOG = "dialog";
-
-/**
-* Initializes the class's configurable properties which can be changed using the Dialog's Config object (cfg).
-* @method initDefaultConfig
-*/
-YAHOO.widget.Dialog.prototype.initDefaultConfig = function() {
-	YAHOO.widget.Dialog.superclass.initDefaultConfig.call(this);
-
-	/**
-	* The internally maintained callback object for use with the Connection utility
-	* @property callback
-	* @type Object
-	*/
-	this.callback = {
-		/**
-		* The function to execute upon success of the Connection submission
-		* @property callback.success
-		* @type Function
-		*/
-		success : null,
-		/**
-		* The function to execute upon failure of the Connection submission
-		* @property callback.failure
-		* @type Function
-		*/
-		failure : null,
-		/**
-		* The arbitraty argument or arguments to pass to the Connection callback functions
-		* @property callback.argument
-		* @type Object
-		*/
-		argument: null
-	};
-
-	// Add form dialog config properties //
-
-	/**
-	* The method to use for posting the Dialog's form. Possible values are "async", "form", and "manual".
-	* @config postmethod
-	* @type String
-	* @default async
-	*/
-	this.cfg.addProperty("postmethod", { value:"async", handler:this.configPostMethod, validator:function(val) {
-													if (val != "form" && val != "async" && val != "none" && val != "manual") {
-														return false;
-													} else {
-														return true;
-													}
-												} });
-
-	/**
-	* Object literal(s) defining the buttons for the Dialog's footer.
-	* @config buttons
-	* @type Object[]
-	* @default "none"
-	*/
-	this.cfg.addProperty("buttons",		{ value:"none",	handler:this.configButtons } );
-};
-
-/**
-* Initializes the custom events for Dialog which are fired automatically at appropriate times by the Dialog class.
-* @method initEvents
-*/
-YAHOO.widget.Dialog.prototype.initEvents = function() {
-	YAHOO.widget.Dialog.superclass.initEvents.call(this);
-
-	/**
-	* CustomEvent fired prior to submission
-	* @event beforeSumitEvent
-	*/
-	this.beforeSubmitEvent	= new YAHOO.util.CustomEvent("beforeSubmit");
-
-	/**
-	* CustomEvent fired after submission
-	* @event submitEvent
-	*/
-	this.submitEvent		= new YAHOO.util.CustomEvent("submit");
-
-	/**
-	* CustomEvent fired prior to manual submission
-	* @event manualSubmitEvent
-	*/
-	this.manualSubmitEvent	= new YAHOO.util.CustomEvent("manualSubmit");
-
-	/**
-	* CustomEvent fired prior to asynchronous submission
-	* @event asyncSubmitEvent
-	*/
-	this.asyncSubmitEvent	= new YAHOO.util.CustomEvent("asyncSubmit");
-
-	/**
-	* CustomEvent fired prior to form-based submission
-	* @event formSubmitEvent
-	*/
-	this.formSubmitEvent	= new YAHOO.util.CustomEvent("formSubmit");
-
-	/**
-	* CustomEvent fired after cancel
-	* @event cancelEvent
-	*/
-	this.cancelEvent		= new YAHOO.util.CustomEvent("cancel");
-};
-
-/**
-* The Dialog initialization method, which is executed for Dialog and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
-* @method init
-* @param {String}	el	The element ID representing the Dialog <em>OR</em>
-* @param {HTMLElement}	el	The element representing the Dialog
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Dialog. See configuration documentation for more details.
-*/
-YAHOO.widget.Dialog.prototype.init = function(el, userConfig) {
-	YAHOO.widget.Dialog.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
-
-	this.beforeInitEvent.fire(YAHOO.widget.Dialog);
-
-	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Dialog.CSS_DIALOG);
-
-	this.cfg.setProperty("visible", false);
-
-	if (userConfig) {
-		this.cfg.applyConfig(userConfig, true);
-	}
-
-	this.showEvent.subscribe(this.focusFirst, this, true);
-	this.beforeHideEvent.subscribe(this.blurButtons, this, true);
-
-	this.beforeRenderEvent.subscribe(function() {
-		var buttonCfg = this.cfg.getProperty("buttons");
-		if (buttonCfg && buttonCfg != "none") {
-			if (! this.footer) {
-				this.setFooter("");
-			}
-		}
-	}, this, true);
-
-	this.initEvent.fire(YAHOO.widget.Dialog);
-};
-
-/**
-* Performs the submission of the Dialog form depending on the value of "postmethod" property.
-* @method doSubmit
-*/
-YAHOO.widget.Dialog.prototype.doSubmit = function() {
-	var pm = this.cfg.getProperty("postmethod");
-	switch (pm) {
-		case "async":
-			var method = this.form.getAttribute("method") || 'POST';
-			method = method.toUpperCase();
-			YAHOO.util.Connect.setForm(this.form);
-			var cObj = YAHOO.util.Connect.asyncRequest(method, this.form.getAttribute("action"), this.callback);
-			this.asyncSubmitEvent.fire();
-			break;
-		case "form":
-			this.form.submit();
-			this.formSubmitEvent.fire();
-			break;
-		case "none":
-		case "manual":
-			this.manualSubmitEvent.fire();
-			break;
-	}
-};
-
-/**
-* Prepares the Dialog's internal FORM object, creating one if one is not currently present.
-* @method registerForm
-*/
-YAHOO.widget.Dialog.prototype.registerForm = function() {
-	var form = this.element.getElementsByTagName("FORM")[0];
-
-	if (! form) {
-		var formHTML = "<form name=\"frm_" + this.id + "\" action=\"\"></form>";
-		this.body.innerHTML += formHTML;
-		form = this.element.getElementsByTagName("FORM")[0];
-	}
-
-	this.firstFormElement = function() {
-		for (var f=0;f<form.elements.length;f++ ) {
-			var el = form.elements[f];
-			if (el.focus) {
-				if (el.type && el.type != "hidden") {
-					return el;
-				}
-			}
-		}
-		return null;
-	}();
-
-	this.lastFormElement = function() {
-		for (var f=form.elements.length-1;f>=0;f-- ) {
-			var el = form.elements[f];
-			if (el.focus) {
-				if (el.type && el.type != "hidden") {
-					return el;
-				}
-			}
-		}
-		return null;
-	}();
-
-	this.form = form;
-
-	if (this.cfg.getProperty("modal") && this.form) {
-
-		var me = this;
-
-		var firstElement = this.firstFormElement || this.firstButton;
-		if (firstElement) {
-			this.preventBackTab = new YAHOO.util.KeyListener(firstElement, { shift:true, keys:9 }, {fn:me.focusLast, scope:me, correctScope:true} );
-			this.showEvent.subscribe(this.preventBackTab.enable, this.preventBackTab, true);
-			this.hideEvent.subscribe(this.preventBackTab.disable, this.preventBackTab, true);
-		}
-
-		var lastElement = this.lastButton || this.lastFormElement;
-		if (lastElement) {
-			this.preventTabOut = new YAHOO.util.KeyListener(lastElement, { shift:false, keys:9 }, {fn:me.focusFirst, scope:me, correctScope:true} );
-			this.showEvent.subscribe(this.preventTabOut.enable, this.preventTabOut, true);
-			this.hideEvent.subscribe(this.preventTabOut.disable, this.preventTabOut, true);
-		}
-	}
-};
-
-// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* The default event handler for the "buttons" configuration property
-* @method configButtons
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Dialog.prototype.configButtons = function(type, args, obj) {
-	var buttons = args[0];
-	if (buttons != "none") {
-		this.buttonSpan = null;
-		this.buttonSpan = document.createElement("SPAN");
-		this.buttonSpan.className = "button-group";
-
-		for (var b=0;b<buttons.length;b++) {
-			var button = buttons[b];
-
-			var htmlButton = document.createElement("BUTTON");
-			htmlButton.setAttribute("type", "button");
-
-			if (button.isDefault) {
-				htmlButton.className = "default";
-				this.defaultHtmlButton = htmlButton;
-			}
-
-			htmlButton.appendChild(document.createTextNode(button.text));
-			YAHOO.util.Event.addListener(htmlButton, "click", button.handler, this, true);
-
-			this.buttonSpan.appendChild(htmlButton);
-			button.htmlButton = htmlButton;
-
-			if (b === 0) {
-				this.firstButton = button.htmlButton;
-			}
-
-			if (b == (buttons.length-1)) {
-				this.lastButton = button.htmlButton;
-			}
-
-		}
-
-		this.setFooter(this.buttonSpan);
-
-		this.cfg.refireEvent("iframe");
-		this.cfg.refireEvent("underlay");
-	} else { // Do cleanup
-		if (this.buttonSpan) {
-			if (this.buttonSpan.parentNode) {
-				this.buttonSpan.parentNode.removeChild(this.buttonSpan);
-			}
-
-			this.buttonSpan = null;
-			this.firstButton = null;
-			this.lastButton = null;
-			this.defaultHtmlButton = null;
-		}
-	}
-};
-
-
-/**
-* The default event handler used to focus the first field of the form when the Dialog is shown.
-* @method focusFirst
-*/
-YAHOO.widget.Dialog.prototype.focusFirst = function(type,args,obj) {
-	if (args) {
-		var e = args[1];
-		if (e) {
-			YAHOO.util.Event.stopEvent(e);
-		}
-	}
-
-	if (this.firstFormElement) {
-		this.firstFormElement.focus();
-	} else {
-		this.focusDefaultButton();
-	}
-};
-
-/**
-* Sets the focus to the last button in the button or form element in the Dialog
-* @method focusLast
-*/
-YAHOO.widget.Dialog.prototype.focusLast = function(type,args,obj) {
-	if (args) {
-		var e = args[1];
-		if (e) {
-			YAHOO.util.Event.stopEvent(e);
-		}
-	}
-
-	var buttons = this.cfg.getProperty("buttons");
-	if (buttons && buttons instanceof Array) {
-		this.focusLastButton();
-	} else {
-		if (this.lastFormElement) {
-			this.lastFormElement.focus();
-		}
-	}
-};
-
-/**
-* Sets the focus to the button that is designated as the default. By default, his handler is executed when the show event is fired.
-* @method focusDefaultButton
-*/
-YAHOO.widget.Dialog.prototype.focusDefaultButton = function() {
-	if (this.defaultHtmlButton) {
-		this.defaultHtmlButton.focus();
-	}
-};
-
-/**
-* Blurs all the html buttons
-* @method blurButtons
-*/
-YAHOO.widget.Dialog.prototype.blurButtons = function() {
-	var buttons = this.cfg.getProperty("buttons");
-	if (buttons && buttons instanceof Array) {
-		var html = buttons[0].htmlButton;
-		if (html) {
-			html.blur();
-		}
-	}
-};
-
-/**
-* Sets the focus to the first button in the button list
-* @method focusFirstButton
-*/
-YAHOO.widget.Dialog.prototype.focusFirstButton = function() {
-	var buttons = this.cfg.getProperty("buttons");
-	if (buttons && buttons instanceof Array) {
-		var html = buttons[0].htmlButton;
-		if (html) {
-			html.focus();
-		}
-	}
-};
-
-/**
-* Sets the focus to the first button in the button list
-* @method focusLastButton
-*/
-YAHOO.widget.Dialog.prototype.focusLastButton = function() {
-	var buttons = this.cfg.getProperty("buttons");
-	if (buttons && buttons instanceof Array) {
-		var html = buttons[buttons.length-1].htmlButton;
-		if (html) {
-			html.focus();
-		}
-	}
-};
-
-/**
-* The default event handler for the "postmethod" configuration property
-* @method configPostMethod
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.Dialog.prototype.configPostMethod = function(type, args, obj) {
-	var postmethod = args[0];
-
-	this.registerForm();
-	YAHOO.util.Event.addListener(this.form, "submit", function(e) {
-														YAHOO.util.Event.stopEvent(e);
-														this.submit();
-														this.form.blur();
-													  }, this, true);
-};
-
-// END BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* Built-in function hook for writing a validation function that will be checked for a "true" value prior to a submit. This function, as implemented by default, always returns true, so it should be overridden if validation is necessary.
-* @method validate
-*/
-YAHOO.widget.Dialog.prototype.validate = function() {
-	return true;
-};
-
-/**
-* Executes a submit of the Dialog followed by a hide, if validation is successful.
-* @method submit
-*/
-YAHOO.widget.Dialog.prototype.submit = function() {
-	if (this.validate()) {
-		this.beforeSubmitEvent.fire();
-		this.doSubmit();
-		this.submitEvent.fire();
-		this.hide();
-		return true;
-	} else {
-		return false;
-	}
-};
-
-/**
-* Executes the cancel of the Dialog followed by a hide.
-* @method cancel
-*/
-YAHOO.widget.Dialog.prototype.cancel = function() {
-	this.cancelEvent.fire();
-	this.hide();
-};
-
-/**
-* Returns a JSON-compatible data structure representing the data currently contained in the form.
-* @method getData
-* @return {Object} A JSON object reprsenting the data of the current form.
-*/
-YAHOO.widget.Dialog.prototype.getData = function() {
-	var form = this.form;
-	var data = {};
-
-	if (form) {
-		for (var i=0;i<form.elements.length;i++) {
-			var formItem = form.elements[i];
-			if (formItem) {
-				if (formItem.tagName) { // Got a single form item
-					switch (formItem.tagName) {
-						case "INPUT":
-							switch (formItem.type) {
-								case "checkbox":
-									data[formItem.name] = formItem.checked;
-									break;
-								case "textbox":
-								case "text":
-								case "hidden":
-									data[formItem.name] = formItem.value;
-									break;
-							}
-							break;
-						case "TEXTAREA":
-							data[formItem.name] = formItem.value;
-							break;
-						case "SELECT":
-							var val = [];
-							for (var x=0;x<formItem.options.length;x++)	{
-								var option = formItem.options[x];
-								if (option.selected) {
-									var selval = option.value;
-									if (! selval || selval === "") {
-										selval = option.text;
-									}
-									val[val.length] = selval;
-								}
-							}
-							data[formItem.name] = val;
-							break;
-					}
-				} else if (formItem[0] && formItem[0].tagName) { // this is an array of form items
-					if (formItem[0].tagName == "INPUT") {
-						switch (formItem[0].type) {
-							case "radio":
-								for (var r=0; r<formItem.length; r++) {
-									var radio = formItem[r];
-									if (radio.checked) {
-										data[radio.name] = radio.value;
-										break;
-									}
-								}
-								break;
-							case "checkbox":
-								var cbArray = [];
-								for (var c=0; c<formItem.length; c++) {
-									var check = formItem[c];
-									if (check.checked) {
-										cbArray[cbArray.length] = check.value;
-									}
-								}
-								data[formItem[0].name] = cbArray;
-								break;
-						}
-					}
-				}
-			}
-		}
-	}
-	return data;
-};
-
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String}	The string representation of the Dialog
-*/
-YAHOO.widget.Dialog.prototype.toString = function() {
-	return "Dialog " + this.id;
-};
-
-/**
-* SimpleDialog is a simple implementation of Dialog that can be used to submit a single value. Forms can be processed in 3 ways -- via an asynchronous Connection utility call, a simple form POST or GET, or manually.
-* @namespace YAHOO.widget
-* @class SimpleDialog
-* @extends YAHOO.widget.Dialog
-* @constructor
-* @param {String}	el	The element ID representing the SimpleDialog <em>OR</em>
-* @param {HTMLElement}	el	The element representing the SimpleDialog
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this SimpleDialog. See configuration documentation for more details.
-*/
-YAHOO.widget.SimpleDialog = function(el, userConfig) {
-	YAHOO.widget.SimpleDialog.superclass.constructor.call(this, el, userConfig);
-};
-
-YAHOO.extend(YAHOO.widget.SimpleDialog, YAHOO.widget.Dialog);
-
-/**
-* Constant for the standard network icon for a blocking action
-* @property YAHOO.widget.SimpleDialog.ICON_BLOCK
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.ICON_BLOCK = "nt/ic/ut/bsc/blck16_1.gif";
-
-/**
-* Constant for the standard network icon for alarm
-* @property YAHOO.widget.SimpleDialog.ICON_ALARM
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.ICON_ALARM = "nt/ic/ut/bsc/alrt16_1.gif";
-
-/**
-* Constant for the standard network icon for help
-* @property YAHOO.widget.SimpleDialog.ICON_HELP
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.ICON_HELP  = "nt/ic/ut/bsc/hlp16_1.gif";
-
-/**
-* Constant for the standard network icon for info
-* @property YAHOO.widget.SimpleDialog.ICON_INFO
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.ICON_INFO  = "nt/ic/ut/bsc/info16_1.gif";
-
-/**
-* Constant for the standard network icon for warn
-* @property YAHOO.widget.SimpleDialog.ICON_WARN
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.ICON_WARN  = "nt/ic/ut/bsc/warn16_1.gif";
-
-/**
-* Constant for the standard network icon for a tip
-* @property YAHOO.widget.SimpleDialog.ICON_TIP
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.ICON_TIP   = "nt/ic/ut/bsc/tip16_1.gif";
-
-/**
-* Constant representing the default CSS class used for a SimpleDialog
-* @property YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG = "simple-dialog";
-
-/**
-* Initializes the class's configurable properties which can be changed using the SimpleDialog's Config object (cfg).
-* @method initDefaultConfig
-*/
-YAHOO.widget.SimpleDialog.prototype.initDefaultConfig = function() {
-	YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);
-
-	// Add dialog config properties //
-
-	/**
-	* Sets the informational icon for the SimpleDialog
-	* @config icon
-	* @type String
-	* @default "none"
-	*/
-	this.cfg.addProperty("icon",	{ value:"none",	handler:this.configIcon, suppressEvent:true } );
-
-	/**
-	* Sets the text for the SimpleDialog
-	* @config text
-	* @type String
-	* @default ""
-	*/
-	this.cfg.addProperty("text",	{ value:"", handler:this.configText, suppressEvent:true, supercedes:["icon"] } );
-};
-
-
-/**
-* The SimpleDialog initialization method, which is executed for SimpleDialog and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
-* @method init
-* @param {String}	el	The element ID representing the SimpleDialog <em>OR</em>
-* @param {HTMLElement}	el	The element representing the SimpleDialog
-* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this SimpleDialog. See configuration documentation for more details.
-*/
-YAHOO.widget.SimpleDialog.prototype.init = function(el, userConfig) {
-	YAHOO.widget.SimpleDialog.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
-
-	this.beforeInitEvent.fire(YAHOO.widget.SimpleDialog);
-
-	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG);
-
-	this.cfg.queueProperty("postmethod", "manual");
-
-	if (userConfig) {
-		this.cfg.applyConfig(userConfig, true);
-	}
-
-	this.beforeRenderEvent.subscribe(function() {
-		if (! this.body) {
-			this.setBody("");
-		}
-	}, this, true);
-
-	this.initEvent.fire(YAHOO.widget.SimpleDialog);
-
-};
-/**
-* Prepares the SimpleDialog's internal FORM object, creating one if one is not currently present, and adding the value hidden field.
-* @method registerForm
-*/
-YAHOO.widget.SimpleDialog.prototype.registerForm = function() {
-	YAHOO.widget.SimpleDialog.superclass.registerForm.call(this);
-	this.form.innerHTML += "<input type=\"hidden\" name=\"" + this.id + "\" value=\"\"/>";
-};
-
-// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* Fired when the "icon" property is set.
-* @method configIcon
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.SimpleDialog.prototype.configIcon = function(type,args,obj) {
-	var icon = args[0];
-	if (icon && icon != "none") {
-		var iconHTML = "<img src=\"" + this.imageRoot + icon + "\" class=\"icon\" />";
-		this.body.innerHTML = iconHTML + this.body.innerHTML;
-	}
-};
-
-/**
-* Fired when the "text" property is set.
-* @method configText
-* @param {String} type	The CustomEvent type (usually the property name)
-* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.SimpleDialog.prototype.configText = function(type,args,obj) {
-	var text = args[0];
-	if (text) {
-		this.setBody(text);
-		this.cfg.refireEvent("icon");
-	}
-};
-// END BUILT-IN PROPERTY EVENT HANDLERS //
-
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String}	The string representation of the SimpleDialog
-*/
-YAHOO.widget.SimpleDialog.prototype.toString = function() {
-	return "SimpleDialog " + this.id;
-};
-
-/**
-* ContainerEffect encapsulates animation transitions that are executed when an Overlay is shown or hidden.
-* @namespace YAHOO.widget
-* @class ContainerEffect
-* @constructor
-* @param {YAHOO.widget.Overlay}	overlay		The Overlay that the animation should be associated with
-* @param {Object}	attrIn		The object literal representing the animation arguments to be used for the animate-in transition. The arguments for this literal are: attributes(object, see YAHOO.util.Anim for description), duration(Number), and method(i.e. YAHOO.util.Easing.easeIn).
-* @param {Object}	attrOut		The object literal representing the animation arguments to be used for the animate-out transition. The arguments for this literal are: attributes(object, see YAHOO.util.Anim for description), duration(Number), and method(i.e. YAHOO.util.Easing.easeIn).
-* @param {HTMLElement}	targetElement	Optional. The target element that should be animated during the transition. Defaults to overlay.element.
-* @param {class}	Optional. The animation class to instantiate. Defaults to YAHOO.util.Anim. Other options include YAHOO.util.Motion.
-*/
-YAHOO.widget.ContainerEffect = function(overlay, attrIn, attrOut, targetElement, animClass) {
-	if (! animClass) {
-		animClass = YAHOO.util.Anim;
-	}
-
-	/**
-	* The overlay to animate
-	* @property overlay
-	* @type YAHOO.widget.Overlay
-	*/
-	this.overlay = overlay;
-	/**
-	* The animation attributes to use when transitioning into view
-	* @property attrIn
-	* @type Object
-	*/
-	this.attrIn = attrIn;
-	/**
-	* The animation attributes to use when transitioning out of view
-	* @property attrOut
-	* @type Object
-	*/
-	this.attrOut = attrOut;
-	/**
-	* The target element to be animated
-	* @property targetElement
-	* @type HTMLElement
-	*/
-	this.targetElement = targetElement || overlay.element;
-	/**
-	* The animation class to use for animating the overlay
-	* @property animClass
-	* @type class
-	*/
-	this.animClass = animClass;
-};
-
-/**
-* Initializes the animation classes and events.
-* @method init
-*/
-YAHOO.widget.ContainerEffect.prototype.init = function() {
-	this.beforeAnimateInEvent = new YAHOO.util.CustomEvent("beforeAnimateIn");
-	this.beforeAnimateOutEvent = new YAHOO.util.CustomEvent("beforeAnimateOut");
-
-	this.animateInCompleteEvent = new YAHOO.util.CustomEvent("animateInComplete");
-	this.animateOutCompleteEvent = new YAHOO.util.CustomEvent("animateOutComplete");
-
-	this.animIn = new this.animClass(this.targetElement, this.attrIn.attributes, this.attrIn.duration, this.attrIn.method);
-	this.animIn.onStart.subscribe(this.handleStartAnimateIn, this);
-	this.animIn.onTween.subscribe(this.handleTweenAnimateIn, this);
-	this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn, this);
-
-	this.animOut = new this.animClass(this.targetElement, this.attrOut.attributes, this.attrOut.duration, this.attrOut.method);
-	this.animOut.onStart.subscribe(this.handleStartAnimateOut, this);
-	this.animOut.onTween.subscribe(this.handleTweenAnimateOut, this);
-	this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut, this);
-};
-
-/**
-* Triggers the in-animation.
-* @method animateIn
-*/
-YAHOO.widget.ContainerEffect.prototype.animateIn = function() {
-	this.beforeAnimateInEvent.fire();
-	this.animIn.animate();
-};
-
-/**
-* Triggers the out-animation.
-* @method animateOut
-*/
-YAHOO.widget.ContainerEffect.prototype.animateOut = function() {
-	this.beforeAnimateOutEvent.fire();
-	this.animOut.animate();
-};
-
-/**
-* The default onStart handler for the in-animation.
-* @method handleStartAnimateIn
-* @param {String} type	The CustomEvent type
-* @param {Object[]}	args	The CustomEvent arguments
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.ContainerEffect.prototype.handleStartAnimateIn = function(type, args, obj) { };
-/**
-* The default onTween handler for the in-animation.
-* @method handleTweenAnimateIn
-* @param {String} type	The CustomEvent type
-* @param {Object[]}	args	The CustomEvent arguments
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateIn = function(type, args, obj) { };
-/**
-* The default onComplete handler for the in-animation.
-* @method handleCompleteAnimateIn
-* @param {String} type	The CustomEvent type
-* @param {Object[]}	args	The CustomEvent arguments
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateIn = function(type, args, obj) { };
-
-/**
-* The default onStart handler for the out-animation.
-* @method handleStartAnimateOut
-* @param {String} type	The CustomEvent type
-* @param {Object[]}	args	The CustomEvent arguments
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.ContainerEffect.prototype.handleStartAnimateOut = function(type, args, obj) { };
-/**
-* The default onTween handler for the out-animation.
-* @method handleTweenAnimateOut
-* @param {String} type	The CustomEvent type
-* @param {Object[]}	args	The CustomEvent arguments
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateOut = function(type, args, obj) { };
-/**
-* The default onComplete handler for the out-animation.
-* @method handleCompleteAnimateOut
-* @param {String} type	The CustomEvent type
-* @param {Object[]}	args	The CustomEvent arguments
-* @param {Object} obj	The scope object
-*/
-YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateOut = function(type, args, obj) { };
-
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String}	The string representation of the ContainerEffect
-*/
-YAHOO.widget.ContainerEffect.prototype.toString = function() {
-	var output = "ContainerEffect";
-	if (this.overlay) {
-		output += " [" + this.overlay.toString() + "]";
-	}
-	return output;
-};
-
-/**
-* A pre-configured ContainerEffect instance that can be used for fading an overlay in and out.
-* @method FADE
-* @static
-* @param {Overlay}	overlay	The Overlay object to animate
-* @param {Number}	dur	The duration of the animation
-* @return {ContainerEffect}	The configured ContainerEffect object
-*/
-YAHOO.widget.ContainerEffect.FADE = function(overlay, dur) {
-	var fade = new YAHOO.widget.ContainerEffect(overlay, { attributes:{opacity: {from:0, to:1}}, duration:dur, method:YAHOO.util.Easing.easeIn }, { attributes:{opacity: {to:0}}, duration:dur, method:YAHOO.util.Easing.easeOut}, overlay.element );
-
-	fade.handleStartAnimateIn = function(type,args,obj) {
-		YAHOO.util.Dom.addClass(obj.overlay.element, "hide-select");
-
-		if (! obj.overlay.underlay) {
-			obj.overlay.cfg.refireEvent("underlay");
-		}
-
-		if (obj.overlay.underlay) {
-			obj.initialUnderlayOpacity = YAHOO.util.Dom.getStyle(obj.overlay.underlay, "opacity");
-			obj.overlay.underlay.style.filter = null;
-		}
-
-		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "visible");
-		YAHOO.util.Dom.setStyle(obj.overlay.element, "opacity", 0);
-	};
-
-	fade.handleCompleteAnimateIn = function(type,args,obj) {
-		YAHOO.util.Dom.removeClass(obj.overlay.element, "hide-select");
-
-		if (obj.overlay.element.style.filter) {
-			obj.overlay.element.style.filter = null;
-		}
-
-		if (obj.overlay.underlay) {
-			YAHOO.util.Dom.setStyle(obj.overlay.underlay, "opacity", obj.initialUnderlayOpacity);
-		}
-
-		obj.overlay.cfg.refireEvent("iframe");
-		obj.animateInCompleteEvent.fire();
-	};
-
-	fade.handleStartAnimateOut = function(type, args, obj) {
-		YAHOO.util.Dom.addClass(obj.overlay.element, "hide-select");
-
-		if (obj.overlay.underlay) {
-			obj.overlay.underlay.style.filter = null;
-		}
-	};
-
-	fade.handleCompleteAnimateOut =  function(type, args, obj) {
-		YAHOO.util.Dom.removeClass(obj.overlay.element, "hide-select");
-		if (obj.overlay.element.style.filter) {
-			obj.overlay.element.style.filter = null;
-		}
-		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "hidden");
-		YAHOO.util.Dom.setStyle(obj.overlay.element, "opacity", 1);
-
-		obj.overlay.cfg.refireEvent("iframe");
-
-		obj.animateOutCompleteEvent.fire();
-	};
-
-	fade.init();
-	return fade;
-};
-
-
-/**
-* A pre-configured ContainerEffect instance that can be used for sliding an overlay in and out.
-* @method SLIDE
-* @static
-* @param {Overlay}	overlay	The Overlay object to animate
-* @param {Number}	dur	The duration of the animation
-* @return {ContainerEffect}	The configured ContainerEffect object
-*/
-YAHOO.widget.ContainerEffect.SLIDE = function(overlay, dur) {
-	var x = overlay.cfg.getProperty("x") || YAHOO.util.Dom.getX(overlay.element);
-	var y = overlay.cfg.getProperty("y") || YAHOO.util.Dom.getY(overlay.element);
-
-	var clientWidth = YAHOO.util.Dom.getClientWidth();
-	var offsetWidth = overlay.element.offsetWidth;
-
-	var slide = new YAHOO.widget.ContainerEffect(overlay, {
-															attributes:{ points: { to:[x, y] } },
-															duration:dur,
-															method:YAHOO.util.Easing.easeIn
-														},
-														{
-															attributes:{ points: { to:[(clientWidth+25), y] } },
-															duration:dur,
-															method:YAHOO.util.Easing.easeOut
-														},
-														overlay.element,
-														YAHOO.util.Motion);
-
-
-	slide.handleStartAnimateIn = function(type,args,obj) {
-		obj.overlay.element.style.left = (-25-offsetWidth) + "px";
-		obj.overlay.element.style.top  = y + "px";
-	};
-
-	slide.handleTweenAnimateIn = function(type, args, obj) {
-
-
-		var pos = YAHOO.util.Dom.getXY(obj.overlay.element);
-
-		var currentX = pos[0];
-		var currentY = pos[1];
-
-		if (YAHOO.util.Dom.getStyle(obj.overlay.element, "visibility") == "hidden" && currentX < x) {
-			YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "visible");
-		}
-
-		obj.overlay.cfg.setProperty("xy", [currentX,currentY], true);
-		obj.overlay.cfg.refireEvent("iframe");
-	};
-
-	slide.handleCompleteAnimateIn = function(type, args, obj) {
-		obj.overlay.cfg.setProperty("xy", [x,y], true);
-		obj.startX = x;
-		obj.startY = y;
-		obj.overlay.cfg.refireEvent("iframe");
-		obj.animateInCompleteEvent.fire();
-	};
-
-	slide.handleStartAnimateOut = function(type, args, obj) {
-		var vw = YAHOO.util.Dom.getViewportWidth();
-
-		var pos = YAHOO.util.Dom.getXY(obj.overlay.element);
-
-		var yso = pos[1];
-
-		var currentTo = obj.animOut.attributes.points.to;
-		obj.animOut.attributes.points.to = [(vw+25), yso];
-	};
-
-	slide.handleTweenAnimateOut = function(type, args, obj) {
-		var pos = YAHOO.util.Dom.getXY(obj.overlay.element);
-
-		var xto = pos[0];
-		var yto = pos[1];
-
-		obj.overlay.cfg.setProperty("xy", [xto,yto], true);
-		obj.overlay.cfg.refireEvent("iframe");
-	};
-
-	slide.handleCompleteAnimateOut = function(type, args, obj) {
-		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "hidden");
-
-		obj.overlay.cfg.setProperty("xy", [x,y]);
-		obj.animateOutCompleteEvent.fire();
-	};
-
-	slide.init();
-	return slide;
-};
\ No newline at end of file
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/**
+* Config is a utility used within an Object to allow the implementer to maintain a list of local configuration properties and listen for changes to those properties dynamically using CustomEvent. The initial values are also maintained so that the configuration can be reset at any given point to its initial state.
+* @namespace YAHOO.util
+* @class Config
+* @constructor
+* @param {Object}	owner	The owner Object to which this Config Object belongs
+*/
+YAHOO.util.Config = function(owner) {
+	if (owner) {
+		this.init(owner);
+	}
+};
+
+/**
+ * Constant representing the CustomEvent type for the config changed event.
+ * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
+ * @private
+ * @static
+ * @final
+ */
+YAHOO.util.Config.CONFIG_CHANGED_EVENT = "configChanged";
+
+/**
+ * Constant representing the boolean type string
+ * @property YAHOO.util.Config.BOOLEAN_TYPE
+ * @private
+ * @static
+ * @final
+ */
+YAHOO.util.Config.BOOLEAN_TYPE = "boolean";
+
+YAHOO.util.Config.prototype = {
+	
+	/**
+	* Object reference to the owner of this Config Object
+	* @property owner
+	* @type Object
+	*/
+	owner : null,
+
+	/**
+	* Boolean flag that specifies whether a queue is currently being executed
+	* @property queueInProgress
+	* @type Boolean
+	*/
+	queueInProgress : false,
+
+	/**
+	* Maintains the local collection of configuration property objects and their specified values
+	* @property config
+	* @private
+	* @type Object
+	*/ 
+	config : null,
+
+	/**
+	* Maintains the local collection of configuration property objects as they were initially applied.
+	* This object is used when resetting a property.
+	* @property initialConfig
+	* @private
+	* @type Object
+	*/ 
+	initialConfig : null,
+
+	/**
+	* Maintains the local, normalized CustomEvent queue
+	* @property eventQueue
+	* @private
+	* @type Object
+	*/ 
+	eventQueue : null,
+
+	/**
+	* Custom Event, notifying subscribers when Config properties are set (setProperty is called without the silent flag
+	* @event configChangedEvent
+	*/
+	configChangedEvent : null,
+
+	/**
+	* Validates that the value passed in is a Boolean.
+	* @method checkBoolean
+	* @param	{Object}	val	The value to validate
+	* @return	{Boolean}	true, if the value is valid
+	*/	
+	checkBoolean: function(val) {
+		return (typeof val == YAHOO.util.Config.BOOLEAN_TYPE);
+	},
+
+	/**
+	* Validates that the value passed in is a number.
+	* @method checkNumber
+	* @param	{Object}	val	The value to validate
+	* @return	{Boolean}	true, if the value is valid
+	*/
+	checkNumber: function(val) {
+		return (!isNaN(val));
+	},
+
+	/**
+	* Fires a configuration property event using the specified value. 
+	* @method fireEvent
+	* @private
+	* @param {String}	key			The configuration property's name
+	* @param {value}	Object		The value of the correct type for the property
+	*/ 
+	fireEvent : function( key, value ) {
+		var property = this.config[key];
+
+		if (property && property.event) {
+			property.event.fire(value);
+		}	
+	},
+
+	/**
+	* Adds a property to the Config Object's private config hash.
+	* @method addProperty
+	* @param {String}	key	The configuration property's name
+	* @param {Object}	propertyObject	The Object containing all of this property's arguments
+	*/
+	addProperty : function( key, propertyObject ) {
+		key = key.toLowerCase();
+
+		this.config[key] = propertyObject;
+
+		propertyObject.event = new YAHOO.util.CustomEvent(key, this.owner);
+		propertyObject.key = key;
+
+		if (propertyObject.handler) {
+			propertyObject.event.subscribe(propertyObject.handler, this.owner);
+		}
+
+		this.setProperty(key, propertyObject.value, true);
+		
+		if (! propertyObject.suppressEvent) {
+			this.queueProperty(key, propertyObject.value);
+		}
+		
+	},
+
+	/**
+	* Returns a key-value configuration map of the values currently set in the Config Object.
+	* @method getConfig
+	* @return {Object} The current config, represented in a key-value map
+	*/
+	getConfig : function() {
+		var cfg = {};
+			
+		for (var prop in this.config) {
+			var property = this.config[prop];
+			if (property && property.event) {
+				cfg[prop] = property.value;
+			}
+		}
+		
+		return cfg;
+	},
+
+	/**
+	* Returns the value of specified property.
+	* @method getProperty
+	* @param {String} key	The name of the property
+	* @return {Object}		The value of the specified property
+	*/
+	getProperty : function(key) {
+		var property = this.config[key.toLowerCase()];
+		if (property && property.event) {
+			return property.value;
+		} else {
+			return undefined;
+		}
+	},
+
+	/**
+	* Resets the specified property's value to its initial value.
+	* @method resetProperty
+	* @param {String} key	The name of the property
+	* @return {Boolean} True is the property was reset, false if not
+	*/
+	resetProperty : function(key) {
+		key = key.toLowerCase();
+
+		var property = this.config[key];
+		if (property && property.event) {
+			if (this.initialConfig[key] && !YAHOO.lang.isUndefined(this.initialConfig[key]))	{
+				this.setProperty(key, this.initialConfig[key]);
+			}
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Sets the value of a property. If the silent property is passed as true, the property's event will not be fired.
+	* @method setProperty
+	* @param {String} key		The name of the property
+	* @param {String} value		The value to set the property to
+	* @param {Boolean} silent	Whether the value should be set silently, without firing the property event.
+	* @return {Boolean}			True, if the set was successful, false if it failed.
+	*/
+	setProperty : function(key, value, silent) {
+		key = key.toLowerCase();
+
+		if (this.queueInProgress && ! silent) {
+			this.queueProperty(key,value); // Currently running through a queue... 
+			return true;
+		} else {
+			var property = this.config[key];
+			if (property && property.event) {
+				if (property.validator && ! property.validator(value)) { // validator
+					return false;
+				} else {
+					property.value = value;
+					if (! silent) {
+						this.fireEvent(key, value);
+						this.configChangedEvent.fire([key, value]);
+					}
+					return true;
+				}
+			} else {
+				return false;
+			}
+		}
+	},
+
+	/**
+	* Sets the value of a property and queues its event to execute. If the event is already scheduled to execute, it is
+	* moved from its current position to the end of the queue.
+	* @method queueProperty
+	* @param {String} key	The name of the property
+	* @param {String} value	The value to set the property to
+	* @return {Boolean}		true, if the set was successful, false if it failed.
+	*/	
+	queueProperty : function(key, value) {
+		key = key.toLowerCase();
+
+		var property = this.config[key];
+							
+		if (property && property.event) {
+			if (!YAHOO.lang.isUndefined(value) && property.validator && ! property.validator(value)) { // validator
+				return false;
+			} else {
+
+				if (!YAHOO.lang.isUndefined(value)) {
+					property.value = value;
+				} else {
+					value = property.value;
+				}
+
+				var foundDuplicate = false;
+				var iLen = this.eventQueue.length;
+				for (var i=0; i < iLen; i++) {
+					var queueItem = this.eventQueue[i];
+
+					if (queueItem) {
+						var queueItemKey = queueItem[0];
+						var queueItemValue = queueItem[1];
+						
+						if (queueItemKey == key) {
+							// found a dupe... push to end of queue, null current item, and break
+							this.eventQueue[i] = null;
+							this.eventQueue.push([key, (!YAHOO.lang.isUndefined(value) ? value : queueItemValue)]);
+							foundDuplicate = true;
+							break;
+						}
+					}
+				}
+				
+				if (! foundDuplicate && !YAHOO.lang.isUndefined(value)) { // this is a refire, or a new property in the queue
+					this.eventQueue.push([key, value]);
+				}
+			}
+
+			if (property.supercedes) {
+				var sLen = property.supercedes.length;
+				for (var s=0; s < sLen; s++) {
+					var supercedesCheck = property.supercedes[s];
+					var qLen = this.eventQueue.length;
+					for (var q=0; q < qLen; q++) {
+						var queueItemCheck = this.eventQueue[q];
+
+						if (queueItemCheck) {
+							var queueItemCheckKey = queueItemCheck[0];
+							var queueItemCheckValue = queueItemCheck[1];
+							
+							if ( queueItemCheckKey == supercedesCheck.toLowerCase() ) {
+								this.eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
+								this.eventQueue[q] = null;
+								break;
+							}
+						}
+					}
+				}
+			}
+
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Fires the event for a property using the property's current value.
+	* @method refireEvent
+	* @param {String} key	The name of the property
+	*/
+	refireEvent : function(key) {
+		key = key.toLowerCase();
+
+		var property = this.config[key];
+		if (property && property.event && !YAHOO.lang.isUndefined(property.value)) {
+			if (this.queueInProgress) {
+				this.queueProperty(key);
+			} else {
+				this.fireEvent(key, property.value);
+			}
+		}
+	},
+
+	/**
+	* Applies a key-value Object literal to the configuration, replacing any existing values, and queueing the property events.
+	* Although the values will be set, fireQueue() must be called for their associated events to execute.
+	* @method applyConfig
+	* @param {Object}	userConfig	The configuration Object literal
+	* @param {Boolean}	init		When set to true, the initialConfig will be set to the userConfig passed in, so that calling a reset will reset the properties to the passed values.
+	*/
+	applyConfig : function(userConfig, init) {
+		if (init) {
+			this.initialConfig = userConfig;
+		}
+		for (var prop in userConfig) {
+			this.queueProperty(prop, userConfig[prop]);
+		}
+	},
+
+	/**
+	* Refires the events for all configuration properties using their current values.
+	* @method refresh
+	*/
+	refresh : function() {
+		for (var prop in this.config) {
+			this.refireEvent(prop);
+		}
+	},
+
+	/**
+	* Fires the normalized list of queued property change events
+	* @method fireQueue
+	*/
+	fireQueue : function() {
+		this.queueInProgress = true;
+		for (var i=0;i<this.eventQueue.length;i++) {
+			var queueItem = this.eventQueue[i];
+			if (queueItem) {
+				var key = queueItem[0];
+				var value = queueItem[1];
+				
+				var property = this.config[key];
+				property.value = value;
+
+				this.fireEvent(key,value);
+			}
+		}
+		
+		this.queueInProgress = false;
+		this.eventQueue = [];
+	},
+
+	/**
+	* Subscribes an external handler to the change event for any given property. 
+	* @method subscribeToConfigEvent
+	* @param {String}	key			The property name
+	* @param {Function}	handler		The handler function to use subscribe to the property's event
+	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
+	* @param {Boolean}	override	Optional. If true, will override "this" within the handler to map to the scope Object passed into the method.
+	* @return {Boolean}				True, if the subscription was successful, otherwise false.
+	*/	
+	subscribeToConfigEvent : function(key, handler, obj, override) {
+		var property = this.config[key.toLowerCase()];
+		if (property && property.event) {
+			if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, obj)) {
+				property.event.subscribe(handler, obj, override);
+			}
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Unsubscribes an external handler from the change event for any given property. 
+	* @method unsubscribeFromConfigEvent
+	* @param {String}	key			The property name
+	* @param {Function}	handler		The handler function to use subscribe to the property's event
+	* @param {Object}	obj			The Object to use for scoping the event handler (see CustomEvent documentation)
+	* @return {Boolean}				True, if the unsubscription was successful, otherwise false.
+	*/
+	unsubscribeFromConfigEvent : function(key, handler, obj) {
+		var property = this.config[key.toLowerCase()];
+		if (property && property.event) {
+			return property.event.unsubscribe(handler, obj);
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Returns a string representation of the Config object
+	* @method toString
+	* @return {String}	The Config object in string format.
+	*/
+	toString : function() {
+		var output = "Config";
+		if (this.owner) {
+			output += " [" + this.owner.toString() + "]";
+		}
+		return output;
+	},
+
+	/**
+	* Returns a string representation of the Config object's current CustomEvent queue
+	* @method outputEventQueue
+	* @return {String}	The string list of CustomEvents currently queued for execution
+	*/
+	outputEventQueue : function() {
+		var output = "";
+		for (var q=0;q<this.eventQueue.length;q++) {
+			var queueItem = this.eventQueue[q];
+			if (queueItem) {
+				output += queueItem[0] + "=" + queueItem[1] + ", ";
+			}
+		}
+		return output;
+	}
+};
+
+
+/**
+* Initializes the configuration Object and all of its local members.
+* @method init
+* @param {Object}	owner	The owner Object to which this Config Object belongs
+*/
+YAHOO.util.Config.prototype.init = function(owner) {
+	this.owner = owner;
+	this.configChangedEvent = new YAHOO.util.CustomEvent(YAHOO.util.CONFIG_CHANGED_EVENT, this);
+	this.queueInProgress = false;
+	this.config = {};
+	this.initialConfig = {};
+	this.eventQueue = [];
+};
+
+/**
+* Checks to determine if a particular function/Object pair are already subscribed to the specified CustomEvent
+* @method YAHOO.util.Config.alreadySubscribed
+* @static
+* @param {YAHOO.util.CustomEvent} evt	The CustomEvent for which to check the subscriptions
+* @param {Function}	fn	The function to look for in the subscribers list
+* @param {Object}	obj	The execution scope Object for the subscription
+* @return {Boolean}	true, if the function/Object pair is already subscribed to the CustomEvent passed in
+*/
+YAHOO.util.Config.alreadySubscribed = function(evt, fn, obj) {
+	for (var e=0;e<evt.subscribers.length;e++) {
+		var subsc = evt.subscribers[e];
+		if (subsc && subsc.obj == obj && subsc.fn == fn) {
+			return true;
+		}
+	}
+	return false;
+};
+/**
+*  The Container family of components is designed to enable developers to create different kinds of content-containing modules on the web. Module and Overlay are the most basic containers, and they can be used directly or extended to build custom containers. Also part of the Container family are four UI controls that extend Module and Overlay: Tooltip, Panel, Dialog, and SimpleDialog.
+* @module container
+* @title Container
+* @requires yahoo,dom,event,dragdrop,animation
+*/
+
+/**
+* Module is a JavaScript representation of the Standard Module Format. Standard Module Format is a simple standard for markup containers where child nodes representing the header, body, and footer of the content are denoted using the CSS classes "hd", "bd", and "ft" respectively. Module is the base class for all other classes in the YUI Container package.
+* @namespace YAHOO.widget
+* @class Module
+* @constructor
+* @param {String} el			The element ID representing the Module <em>OR</em>
+* @param {HTMLElement} el		The element representing the Module
+* @param {Object} userConfig	The configuration Object literal containing the configuration that should be set for this module. See configuration documentation for more details.
+*/
+YAHOO.widget.Module = function(el, userConfig) {
+	if (el) {
+		this.init(el, userConfig);
+	} else {
+	}
+};
+
+/**
+* Constant representing the prefix path to use for non-secure images
+* @property YAHOO.widget.Module.IMG_ROOT
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.IMG_ROOT = null;
+
+/**
+* Constant representing the prefix path to use for securely served images
+* @property YAHOO.widget.Module.IMG_ROOT_SSL
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.IMG_ROOT_SSL = null;
+
+/**
+* Constant for the default CSS class name that represents a Module
+* @property YAHOO.widget.Module.CSS_MODULE
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.CSS_MODULE = "yui-module";
+
+/**
+* Constant representing the module header
+* @property YAHOO.widget.Module.CSS_HEADER
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.CSS_HEADER = "hd";
+
+/**
+* Constant representing the module body
+* @property YAHOO.widget.Module.CSS_BODY
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.CSS_BODY = "bd";
+
+/**
+* Constant representing the module footer
+* @property YAHOO.widget.Module.CSS_FOOTER
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.CSS_FOOTER = "ft";
+
+/**
+* Constant representing the url for the "src" attribute of the iframe used to monitor changes to the browser's base font size
+* @property YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL = "javascript:false;";
+
+/**
+* Singleton CustomEvent fired when the font size is changed in the browser.
+* Opera's "zoom" functionality currently does not support text size detection.
+* @event YAHOO.widget.Module.textResizeEvent
+*/
+YAHOO.widget.Module.textResizeEvent = new YAHOO.util.CustomEvent("textResize");
+
+/**
+* Constant representing the name of the Module's events
+* @property YAHOO.widget.Module._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Module._EVENT_TYPES = {
+
+    "BEFORE_INIT": "beforeInit",
+    "INIT": "init",
+    "APPEND": "append",
+    "BEFORE_RENDER": "beforeRender",
+    "RENDER": "render",
+    "CHANGE_HEADER": "changeHeader",
+    "CHANGE_BODY": "changeBody",
+    "CHANGE_FOOTER": "changeFooter",
+    "CHANGE_CONTENT": "changeContent",
+    "DESTORY": "destroy",
+    "BEFORE_SHOW": "beforeShow",
+    "SHOW": "show",
+    "BEFORE_HIDE": "beforeHide",
+    "HIDE": "hide"
+
+};
+    
+/**
+* Constant representing the Module's configuration properties
+* @property YAHOO.widget.Module._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Module._DEFAULT_CONFIG = {
+
+    "VISIBLE": { 
+        key: "visible", 
+        value: true, 
+        validator: YAHOO.lang.isBoolean 
+    },
+
+    "EFFECT": { 
+        key: "effect", 
+        suppressEvent:true, 
+        supercedes:["visible"] 
+    },
+
+    "MONITOR_RESIZE": { 
+        key: "monitorresize", 
+        value:true  
+    }
+
+};
+
+
+YAHOO.widget.Module.prototype = {
+
+	/**
+	* The class's constructor function
+	* @property contructor
+	* @type Function
+	*/
+	constructor : YAHOO.widget.Module,
+
+	/**
+	* The main module element that contains the header, body, and footer
+	* @property element
+	* @type HTMLElement
+	*/
+	element : null,
+
+	/**
+	* The header element, denoted with CSS class "hd"
+	* @property header
+	* @type HTMLElement
+	*/
+	header : null,
+
+	/**
+	* The body element, denoted with CSS class "bd"
+	* @property body
+	* @type HTMLElement
+	*/
+	body : null,
+
+	/**
+	* The footer element, denoted with CSS class "ft"
+	* @property footer
+	* @type HTMLElement
+	*/
+	footer : null,
+
+	/**
+	* The id of the element
+	* @property id
+	* @type String
+	*/
+	id : null,
+
+	/**
+	* The String representing the image root
+	* @property imageRoot
+	* @type String
+	*/
+	imageRoot : YAHOO.widget.Module.IMG_ROOT,
+
+	/**
+	* Initializes the custom events for Module which are fired automatically at appropriate times by the Module class.
+	* @method initEvents
+	*/
+	initEvents : function() {
+
+        var EVENT_TYPES = YAHOO.widget.Module._EVENT_TYPES;
+
+		/**
+		* CustomEvent fired prior to class initalization.
+		* @event beforeInitEvent
+		* @param {class} classRef	class reference of the initializing class, such as this.beforeInitEvent.fire(YAHOO.widget.Module)
+		*/
+		this.beforeInitEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_INIT, this);
+
+		/**
+		* CustomEvent fired after class initalization.
+		* @event initEvent
+		* @param {class} classRef	class reference of the initializing class, such as this.beforeInitEvent.fire(YAHOO.widget.Module)
+		*/		
+		this.initEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.INIT, this);
+
+		/**
+		* CustomEvent fired when the Module is appended to the DOM
+		* @event appendEvent
+		*/
+		this.appendEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.APPEND, this);
+
+		/**
+		* CustomEvent fired before the Module is rendered
+		* @event beforeRenderEvent
+		*/
+		this.beforeRenderEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_RENDER, this);
+
+		/**
+		* CustomEvent fired after the Module is rendered
+		* @event renderEvent
+		*/
+		this.renderEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.RENDER, this);
+	
+		/**
+		* CustomEvent fired when the header content of the Module is modified
+		* @event changeHeaderEvent
+		* @param {String/HTMLElement} content	String/element representing the new header content
+		*/
+		this.changeHeaderEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_HEADER, this);
+		
+		/**
+		* CustomEvent fired when the body content of the Module is modified
+		* @event changeBodyEvent
+		* @param {String/HTMLElement} content	String/element representing the new body content
+		*/		
+		this.changeBodyEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_BODY, this);
+		
+		/**
+		* CustomEvent fired when the footer content of the Module is modified
+		* @event changeFooterEvent
+		* @param {String/HTMLElement} content	String/element representing the new footer content
+		*/
+		this.changeFooterEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_FOOTER, this);
+
+		/**
+		* CustomEvent fired when the content of the Module is modified
+		* @event changeContentEvent
+		*/
+		this.changeContentEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.CHANGE_CONTENT, this);
+
+		/**
+		* CustomEvent fired when the Module is destroyed
+		* @event destroyEvent
+		*/
+		this.destroyEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.DESTORY, this);
+		
+		/**
+		* CustomEvent fired before the Module is shown
+		* @event beforeShowEvent
+		*/
+		this.beforeShowEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_SHOW, this);
+
+		/**
+		* CustomEvent fired after the Module is shown
+		* @event showEvent
+		*/
+		this.showEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.SHOW, this);
+
+		/**
+		* CustomEvent fired before the Module is hidden
+		* @event beforeHideEvent
+		*/
+		this.beforeHideEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_HIDE, this);
+
+		/**
+		* CustomEvent fired after the Module is hidden
+		* @event hideEvent
+		*/
+		this.hideEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.HIDE, this);
+	}, 
+
+	/**
+	* String representing the current user-agent platform
+	* @property platform
+	* @type String
+	*/
+	platform : function() {
+					var ua = navigator.userAgent.toLowerCase();
+					if (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1) {
+						return "windows";
+					} else if (ua.indexOf("macintosh") != -1) {
+						return "mac";
+					} else {
+						return false;
+					}
+				}(),
+
+	/**
+	* String representing the current user-agent browser
+	* @property browser
+	* @type String
+	*/
+	browser : function() {
+			var ua = navigator.userAgent.toLowerCase();
+				  if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
+					 return 'opera';
+				  } else if (ua.indexOf('msie 7')!=-1) { // IE7
+					 return 'ie7';
+				  } else if (ua.indexOf('msie') !=-1) { // IE
+					 return 'ie';
+				  } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
+					 return 'safari';
+				  } else if (ua.indexOf('gecko') != -1) { // Gecko
+					 return 'gecko';
+				  } else {
+					 return false;
+				  }
+			}(),
+
+	/**
+	* Boolean representing whether or not the current browsing context is secure (https)
+	* @property isSecure
+	* @type Boolean
+	*/
+	isSecure : function() {
+		if (window.location.href.toLowerCase().indexOf("https") === 0) {
+			return true;
+		} else {
+			return false;
+		}
+	}(),
+
+	/**
+	* Initializes the custom events for Module which are fired automatically at appropriate times by the Module class.
+	*/
+	initDefaultConfig : function() {
+		// Add properties //
+
+    	var DEFAULT_CONFIG = YAHOO.widget.Module._DEFAULT_CONFIG;
+
+		/**
+		* Specifies whether the Module is visible on the page.
+		* @config visible
+		* @type Boolean
+		* @default true
+		*/
+		this.cfg.addProperty(
+		          DEFAULT_CONFIG.VISIBLE.key, 
+		          {
+		              handler: this.configVisible, 
+		              value: DEFAULT_CONFIG.VISIBLE.value, 
+		              validator: DEFAULT_CONFIG.VISIBLE.validator
+                  }
+              );
+
+		/**
+		* Object or array of objects representing the ContainerEffect classes that are active for animating the container.
+		* @config effect
+		* @type Object
+		* @default null
+		*/
+		this.cfg.addProperty(
+                    DEFAULT_CONFIG.EFFECT.key, 
+                    {
+                        suppressEvent: DEFAULT_CONFIG.EFFECT.suppressEvent, 
+                        supercedes: DEFAULT_CONFIG.EFFECT.supercedes
+                    }
+                );
+
+		/**
+		* Specifies whether to create a special proxy iframe to monitor for user font resizing in the document
+		* @config monitorresize
+		* @type Boolean
+		* @default true
+		*/
+		this.cfg.addProperty(
+		          DEFAULT_CONFIG.MONITOR_RESIZE.key,
+		          {
+		              handler: this.configMonitorResize,
+		              value: DEFAULT_CONFIG.MONITOR_RESIZE.value
+                  }
+              );
+		
+	},
+
+	/**
+	* The Module class's initialization method, which is executed for Module and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
+	* @method init
+	* @param {String}	el	The element ID representing the Module <em>OR</em>
+	* @param {HTMLElement}	el	The element representing the Module
+	* @param {Object}	userConfig	The configuration Object literal containing the configuration that should be set for this module. See configuration documentation for more details.
+	*/
+	init : function(el, userConfig) {
+
+		this.initEvents();
+
+		this.beforeInitEvent.fire(YAHOO.widget.Module);
+
+		/**
+		* The Module's Config object used for monitoring configuration properties.
+		* @property cfg
+		* @type YAHOO.util.Config
+		*/
+		this.cfg = new YAHOO.util.Config(this);
+
+		if (this.isSecure) {
+			this.imageRoot = YAHOO.widget.Module.IMG_ROOT_SSL;
+		}
+
+		if (typeof el == "string") {
+			var elId = el;
+
+			el = document.getElementById(el);
+			if (! el) {
+				el = document.createElement("div");
+				el.id = elId;
+			}
+		}
+
+		this.element = el;
+
+		if (el.id) {
+			this.id = el.id;
+		}
+
+		var childNodes = this.element.childNodes;
+
+		if (childNodes) {
+			for (var i=0;i<childNodes.length;i++) {
+				var child = childNodes[i];
+				switch (child.className) {
+					case YAHOO.widget.Module.CSS_HEADER:
+						this.header = child;
+						break;
+					case YAHOO.widget.Module.CSS_BODY:
+						this.body = child;
+						break;
+					case YAHOO.widget.Module.CSS_FOOTER:
+						this.footer = child;
+						break;
+				}
+			}
+		}
+
+		this.initDefaultConfig();
+
+		YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Module.CSS_MODULE);
+
+		if (userConfig) {
+			this.cfg.applyConfig(userConfig, true);
+		}
+
+		// Subscribe to the fireQueue() method of Config so that any queued configuration changes are
+		// excecuted upon render of the Module
+		if (! YAHOO.util.Config.alreadySubscribed(this.renderEvent, this.cfg.fireQueue, this.cfg)) {
+			this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true);
+		}
+
+		this.initEvent.fire(YAHOO.widget.Module);
+	},
+
+	/**
+	* Initialized an empty IFRAME that is placed out of the visible area that can be used to detect text resize.
+	* @method initResizeMonitor
+	*/
+	initResizeMonitor : function() {
+
+        if(this.browser != "opera") {
+
+            var resizeMonitor = document.getElementById("_yuiResizeMonitor");
+
+            if (! resizeMonitor) {
+
+                resizeMonitor = document.createElement("iframe");
+
+                var bIE = (this.browser.indexOf("ie") === 0);
+
+                if(this.isSecure && YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL && bIE) {
+                   resizeMonitor.src = YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL;
+                }
+
+                resizeMonitor.id = "_yuiResizeMonitor";
+                resizeMonitor.style.visibility = "hidden";
+
+                document.body.appendChild(resizeMonitor);
+
+                resizeMonitor.style.width = "10em";
+                resizeMonitor.style.height = "10em";
+                resizeMonitor.style.position = "absolute";
+
+                var nLeft = -1 * resizeMonitor.offsetWidth;
+                var nTop = -1 * resizeMonitor.offsetHeight;
+
+                resizeMonitor.style.top = nTop + "px";
+                resizeMonitor.style.left = nLeft + "px";
+                resizeMonitor.style.borderStyle = "none";
+                resizeMonitor.style.borderWidth = "0";
+                YAHOO.util.Dom.setStyle(resizeMonitor, "opacity", "0");
+
+                resizeMonitor.style.visibility = "visible";
+
+                if(!bIE) {
+
+                    var doc = resizeMonitor.contentWindow.document;
+
+                    doc.open();
+                    doc.close();
+
+                }
+            }
+
+			var fireTextResize = function() {
+				YAHOO.widget.Module.textResizeEvent.fire();
+			};
+
+            if(resizeMonitor && resizeMonitor.contentWindow) {
+                this.resizeMonitor = resizeMonitor;
+
+				YAHOO.widget.Module.textResizeEvent.subscribe(this.onDomResize, this, true);
+
+				if (! YAHOO.widget.Module.textResizeInitialized) {
+					if (! YAHOO.util.Event.addListener(this.resizeMonitor.contentWindow, "resize", fireTextResize)) {
+						// This will fail in IE if document.domain has changed, so we must change the listener to
+						// use the resizeMonitor element instead
+						YAHOO.util.Event.addListener(this.resizeMonitor, "resize", fireTextResize);
+					}
+					YAHOO.widget.Module.textResizeInitialized = true;
+				}
+            }
+
+        }
+
+	},
+
+	/**
+	* Event handler fired when the resize monitor element is resized.
+	* @method onDomResize
+	* @param {DOMEvent} e	The DOM resize event
+	* @param {Object} obj	The scope object passed to the handler
+	*/
+	onDomResize : function(e, obj) {
+
+        var nLeft = -1 * this.resizeMonitor.offsetWidth,
+            nTop = -1 * this.resizeMonitor.offsetHeight;
+
+        this.resizeMonitor.style.top = nTop + "px";
+        this.resizeMonitor.style.left =  nLeft + "px";
+
+	},
+
+	/**
+	* Sets the Module's header content to the HTML specified, or appends the passed element to the header. If no header is present, one will be automatically created.
+	* @method setHeader
+	* @param {String}	headerContent	The HTML used to set the header <em>OR</em>
+	* @param {HTMLElement}	headerContent	The HTMLElement to append to the header
+	*/
+	setHeader : function(headerContent) {
+		if (! this.header) {
+			this.header = document.createElement("div");
+			this.header.className = YAHOO.widget.Module.CSS_HEADER;
+		}
+
+		if (typeof headerContent == "string") {
+			this.header.innerHTML = headerContent;
+		} else {
+			this.header.innerHTML = "";
+			this.header.appendChild(headerContent);
+		}
+
+		this.changeHeaderEvent.fire(headerContent);
+		this.changeContentEvent.fire();
+	},
+
+	/**
+	* Appends the passed element to the header. If no header is present, one will be automatically created.
+	* @method appendToHeader
+	* @param {HTMLElement}	element	The element to append to the header
+	*/
+	appendToHeader : function(element) {
+		if (! this.header) {
+			this.header = document.createElement("div");
+			this.header.className = YAHOO.widget.Module.CSS_HEADER;
+		}
+
+		this.header.appendChild(element);
+		this.changeHeaderEvent.fire(element);
+		this.changeContentEvent.fire();
+	},
+
+	/**
+	* Sets the Module's body content to the HTML specified, or appends the passed element to the body. If no body is present, one will be automatically created.
+	* @method setBody
+	* @param {String}	bodyContent	The HTML used to set the body <em>OR</em>
+	* @param {HTMLElement}	bodyContent	The HTMLElement to append to the body
+	*/
+	setBody : function(bodyContent) {
+		if (! this.body) {
+			this.body = document.createElement("div");
+			this.body.className = YAHOO.widget.Module.CSS_BODY;
+		}
+
+		if (typeof bodyContent == "string")
+		{
+			this.body.innerHTML = bodyContent;
+		} else {
+			this.body.innerHTML = "";
+			this.body.appendChild(bodyContent);
+		}
+
+		this.changeBodyEvent.fire(bodyContent);
+		this.changeContentEvent.fire();
+	},
+
+	/**
+	* Appends the passed element to the body. If no body is present, one will be automatically created.
+	* @method appendToBody
+	* @param {HTMLElement}	element	The element to append to the body
+	*/
+	appendToBody : function(element) {
+		if (! this.body) {
+			this.body = document.createElement("div");
+			this.body.className = YAHOO.widget.Module.CSS_BODY;
+		}
+
+		this.body.appendChild(element);
+		this.changeBodyEvent.fire(element);
+		this.changeContentEvent.fire();
+	},
+
+	/**
+	* Sets the Module's footer content to the HTML specified, or appends the passed element to the footer. If no footer is present, one will be automatically created.
+	* @method setFooter
+	* @param {String}	footerContent	The HTML used to set the footer <em>OR</em>
+	* @param {HTMLElement}	footerContent	The HTMLElement to append to the footer
+	*/
+	setFooter : function(footerContent) {
+		if (! this.footer) {
+			this.footer = document.createElement("div");
+			this.footer.className = YAHOO.widget.Module.CSS_FOOTER;
+		}
+
+		if (typeof footerContent == "string") {
+			this.footer.innerHTML = footerContent;
+		} else {
+			this.footer.innerHTML = "";
+			this.footer.appendChild(footerContent);
+		}
+
+		this.changeFooterEvent.fire(footerContent);
+		this.changeContentEvent.fire();
+	},
+
+	/**
+	* Appends the passed element to the footer. If no footer is present, one will be automatically created.
+	* @method appendToFooter
+	* @param {HTMLElement}	element	The element to append to the footer
+	*/
+	appendToFooter : function(element) {
+		if (! this.footer) {
+			this.footer = document.createElement("div");
+			this.footer.className = YAHOO.widget.Module.CSS_FOOTER;
+		}
+
+		this.footer.appendChild(element);
+		this.changeFooterEvent.fire(element);
+		this.changeContentEvent.fire();
+	},
+
+	/**
+	* Renders the Module by inserting the elements that are not already in the main Module into their correct places. Optionally appends the Module to the specified node prior to the render's execution. NOTE: For Modules without existing markup, the appendToNode argument is REQUIRED. If this argument is ommitted and the current element is not present in the document, the function will return false, indicating that the render was a failure.
+	* @method render
+	* @param {String}	appendToNode	The element id to which the Module should be appended to prior to rendering <em>OR</em>
+	* @param {HTMLElement}	appendToNode	The element to which the Module should be appended to prior to rendering
+	* @param {HTMLElement}	moduleElement	OPTIONAL. The element that represents the actual Standard Module container.
+	* @return {Boolean} Success or failure of the render
+	*/
+	render : function(appendToNode, moduleElement) {
+		this.beforeRenderEvent.fire();
+
+		if (! moduleElement) {
+			moduleElement = this.element;
+		}
+
+		var me = this;
+		var appendTo = function(element) {
+			if (typeof element == "string") {
+				element = document.getElementById(element);
+			}
+
+			if (element) {
+				element.appendChild(me.element);
+				me.appendEvent.fire();
+			}
+		};
+
+		if (appendToNode) {
+			appendTo(appendToNode);
+		} else { // No node was passed in. If the element is not pre-marked up, this fails
+			if (! YAHOO.util.Dom.inDocument(this.element)) {
+				return false;
+			}
+		}
+
+		// Need to get everything into the DOM if it isn't already
+
+		if (this.header && ! YAHOO.util.Dom.inDocument(this.header)) {
+			// There is a header, but it's not in the DOM yet... need to add it
+			var firstChild = moduleElement.firstChild;
+			if (firstChild) { // Insert before first child if exists
+				moduleElement.insertBefore(this.header, firstChild);
+			} else { // Append to empty body because there are no children
+				moduleElement.appendChild(this.header);
+			}
+		}
+
+		if (this.body && ! YAHOO.util.Dom.inDocument(this.body)) {
+			// There is a body, but it's not in the DOM yet... need to add it
+			if (this.footer && YAHOO.util.Dom.isAncestor(this.moduleElement, this.footer)) { // Insert before footer if exists in DOM
+				moduleElement.insertBefore(this.body, this.footer);
+			} else { // Append to element because there is no footer
+				moduleElement.appendChild(this.body);
+			}
+		}
+
+		if (this.footer && ! YAHOO.util.Dom.inDocument(this.footer)) {
+			// There is a footer, but it's not in the DOM yet... need to add it
+			moduleElement.appendChild(this.footer);
+		}
+
+		this.renderEvent.fire();
+		return true;
+	},
+
+	/**
+	* Removes the Module element from the DOM and sets all child elements to null.
+	* @method destroy
+	*/
+	destroy : function() {
+		var parent;
+
+		if (this.element) {
+			YAHOO.util.Event.purgeElement(this.element, true);
+			parent = this.element.parentNode;
+		}
+		if (parent) {
+			parent.removeChild(this.element);
+		}
+
+		this.element = null;
+		this.header = null;
+		this.body = null;
+		this.footer = null;
+
+		for (var e in this) {
+			if (e instanceof YAHOO.util.CustomEvent) {
+				e.unsubscribeAll();
+			}
+		}
+
+		YAHOO.widget.Module.textResizeEvent.unsubscribe(this.onDomResize, this);
+
+		this.destroyEvent.fire();
+	},
+
+	/**
+	* Shows the Module element by setting the visible configuration property to true. Also fires two events: beforeShowEvent prior to the visibility change, and showEvent after.
+	* @method show
+	*/
+	show : function() {
+		this.cfg.setProperty("visible", true);
+	},
+
+	/**
+	* Hides the Module element by setting the visible configuration property to false. Also fires two events: beforeHideEvent prior to the visibility change, and hideEvent after.
+	* @method hide
+	*/
+	hide : function() {
+		this.cfg.setProperty("visible", false);
+	},
+
+	// BUILT-IN EVENT HANDLERS FOR MODULE //
+
+	/**
+	* Default event handler for changing the visibility property of a Module. By default, this is achieved by switching the "display" style between "block" and "none".
+	* This method is responsible for firing showEvent and hideEvent.
+	* @param {String} type	The CustomEvent type (usually the property name)
+	* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+	* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+	* @method configVisible
+	*/
+	configVisible : function(type, args, obj) {
+		var visible = args[0];
+		if (visible) {
+			this.beforeShowEvent.fire();
+			YAHOO.util.Dom.setStyle(this.element, "display", "block");
+			this.showEvent.fire();
+		} else {
+			this.beforeHideEvent.fire();
+			YAHOO.util.Dom.setStyle(this.element, "display", "none");
+			this.hideEvent.fire();
+		}
+	},
+
+	/**
+	* Default event handler for the "monitorresize" configuration property
+	* @param {String} type	The CustomEvent type (usually the property name)
+	* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+	* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+	* @method configMonitorResize
+	*/
+	configMonitorResize : function(type, args, obj) {
+		var monitor = args[0];
+		if (monitor) {
+			this.initResizeMonitor();
+		} else {
+			YAHOO.widget.Module.textResizeEvent.unsubscribe(this.onDomResize, this, true);
+			this.resizeMonitor = null;
+		}
+	}
+};
+
+/**
+* Returns a String representation of the Object.
+* @method toString
+* @return {String}	The string representation of the Module
+*/
+YAHOO.widget.Module.prototype.toString = function() {
+	return "Module " + this.id;
+};
+/**
+* Overlay is a Module that is absolutely positioned above the page flow. It has convenience methods for positioning and sizing, as well as options for controlling zIndex and constraining the Overlay's position to the current visible viewport. Overlay also contains a dynamicly generated IFRAME which is placed beneath it for Internet Explorer 6 and 5.x so that it will be properly rendered above SELECT elements.
+* @namespace YAHOO.widget
+* @class Overlay
+* @extends YAHOO.widget.Module
+* @param {String}	el	The element ID representing the Overlay <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Overlay
+* @param {Object}	userConfig	The configuration object literal containing 10/23/2006the configuration that should be set for this Overlay. See configuration documentation for more details.
+* @constructor
+*/
+YAHOO.widget.Overlay = function(el, userConfig) {
+	YAHOO.widget.Overlay.superclass.constructor.call(this, el, userConfig);
+};
+
+YAHOO.extend(YAHOO.widget.Overlay, YAHOO.widget.Module);
+
+/**
+* Constant representing the name of the Overlay's events
+* @property YAHOO.widget.Overlay._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Overlay._EVENT_TYPES = {
+
+    "BEFORE_MOVE": "beforeMove",
+    "MOVE": "move"
+
+};
+
+/**
+* Constant representing the Overlay's configuration properties
+* @property YAHOO.widget.Overlay._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Overlay._DEFAULT_CONFIG = {
+
+    "X": { 
+        key: "x", 
+        validator:YAHOO.lang.isNumber, 
+        suppressEvent:true, supercedes:["iframe"] 
+    },
+
+    "Y": { 
+        key: "y", 
+        validator:YAHOO.lang.isNumber, 
+        suppressEvent:true, supercedes:["iframe"] 
+    },
+
+    "XY": { 
+        key: "xy", 
+        suppressEvent:true, 
+        supercedes:["iframe"] 
+    },
+
+    "CONTEXT": { 
+        key: "context", 
+        suppressEvent:true, 
+        supercedes:["iframe"] 
+    },
+
+    "FIXED_CENTER": { 
+        key: "fixedcenter", 
+        value:false, 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["iframe","visible"] 
+    },
+
+    "WIDTH": { 
+        key: "width", 
+        suppressEvent:true, 
+        supercedes:["iframe"] 
+    }, 
+
+    "HEIGHT": { 
+        key: "height", 
+        suppressEvent:true, 
+        supercedes:["iframe"] 
+    }, 
+
+    "ZINDEX": { 
+        key: "zindex", 
+        value:null 
+    }, 
+
+    "CONSTRAIN_TO_VIEWPORT": { 
+        key: "constraintoviewport", 
+        value:false, 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["iframe","x","y","xy"] 
+    }, 
+
+    "IFRAME": { 
+        key: "iframe", 
+        value:(YAHOO.widget.Module.prototype.browser == "ie" ? true : false), 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["zIndex"] 
+    }
+
+};
+
+/**
+* The URL that will be placed in the iframe
+* @property YAHOO.widget.Overlay.IFRAME_SRC
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Overlay.IFRAME_SRC = "javascript:false;";
+
+/**
+* Constant representing the top left corner of an element, used for configuring the context element alignment
+* @property YAHOO.widget.Overlay.TOP_LEFT
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Overlay.TOP_LEFT = "tl";
+
+/**
+* Constant representing the top right corner of an element, used for configuring the context element alignment
+* @property YAHOO.widget.Overlay.TOP_RIGHT
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Overlay.TOP_RIGHT = "tr";
+
+/**
+* Constant representing the top bottom left corner of an element, used for configuring the context element alignment
+* @property YAHOO.widget.Overlay.BOTTOM_LEFT
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Overlay.BOTTOM_LEFT = "bl";
+
+/**
+* Constant representing the bottom right corner of an element, used for configuring the context element alignment
+* @property YAHOO.widget.Overlay.BOTTOM_RIGHT
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Overlay.BOTTOM_RIGHT = "br";
+
+/**
+* Constant representing the default CSS class used for an Overlay
+* @property YAHOO.widget.Overlay.CSS_OVERLAY
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Overlay.CSS_OVERLAY = "yui-overlay";
+
+/**
+* The Overlay initialization method, which is executed for Overlay and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
+* @method init
+* @param {String}	el	The element ID representing the Overlay <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Overlay
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Overlay. See configuration documentation for more details.
+*/
+YAHOO.widget.Overlay.prototype.init = function(el, userConfig) {
+	YAHOO.widget.Overlay.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
+
+	this.beforeInitEvent.fire(YAHOO.widget.Overlay);
+
+	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Overlay.CSS_OVERLAY);
+
+	if (userConfig) {
+		this.cfg.applyConfig(userConfig, true);
+	}
+
+	if (this.platform == "mac" && this.browser == "gecko") {
+		if (! YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)) {
+			this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);
+		}
+		if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)) {
+			this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);
+		}
+	}
+
+	this.initEvent.fire(YAHOO.widget.Overlay);
+
+};
+
+/**
+* Initializes the custom events for Overlay which are fired automatically at appropriate times by the Overlay class.
+* @method initEvents
+*/
+YAHOO.widget.Overlay.prototype.initEvents = function() {
+	YAHOO.widget.Overlay.superclass.initEvents.call(this);
+
+    var EVENT_TYPES = YAHOO.widget.Overlay._EVENT_TYPES;
+
+	/**
+	* CustomEvent fired before the Overlay is moved.
+	* @event beforeMoveEvent
+	* @param {Number} x	x coordinate
+	* @param {Number} y	y coordinate
+	*/
+	this.beforeMoveEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_MOVE, this);
+
+	/**
+	* CustomEvent fired after the Overlay is moved.
+	* @event moveEvent
+	* @param {Number} x	x coordinate
+	* @param {Number} y	y coordinate
+	*/
+	this.moveEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.MOVE, this);
+};
+
+/**
+* Initializes the class's configurable properties which can be changed using the Overlay's Config object (cfg).
+* @method initDefaultConfig
+*/
+YAHOO.widget.Overlay.prototype.initDefaultConfig = function() {
+	YAHOO.widget.Overlay.superclass.initDefaultConfig.call(this);
+
+
+	// Add overlay config properties //
+
+    var DEFAULT_CONFIG = YAHOO.widget.Overlay._DEFAULT_CONFIG;
+
+	/**
+	* The absolute x-coordinate position of the Overlay
+	* @config x
+	* @type Number
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.X.key, 
+	           { 
+	               handler: this.configX, 
+	               validator: DEFAULT_CONFIG.X.validator, 
+	               suppressEvent: DEFAULT_CONFIG.X.suppressEvent, 
+	               supercedes: DEFAULT_CONFIG.X.supercedes
+               }
+           );
+
+	/**
+	* The absolute y-coordinate position of the Overlay
+	* @config y
+	* @type Number
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.Y.key,
+	           {
+	               handler: this.configY, 
+	               validator: DEFAULT_CONFIG.Y.validator, 
+	               suppressEvent: DEFAULT_CONFIG.Y.suppressEvent, 
+	               supercedes: DEFAULT_CONFIG.Y.supercedes
+               }
+           );
+
+	/**
+	* An array with the absolute x and y positions of the Overlay
+	* @config xy
+	* @type Number[]
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.XY.key,
+	           {
+	               handler: this.configXY, 
+	               suppressEvent: DEFAULT_CONFIG.XY.suppressEvent, 
+	               supercedes: DEFAULT_CONFIG.XY.supercedes
+               }
+           );
+
+	/**
+	* The array of context arguments for context-sensitive positioning. The format is: [id or element, element corner, context corner]. For example, setting this property to ["img1", "tl", "bl"] would align the Overlay's top left corner to the context element's bottom left corner.
+	* @config context
+	* @type Array
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.CONTEXT.key,
+	           {
+	               handler: this.configContext, 
+	               suppressEvent: DEFAULT_CONFIG.CONTEXT.suppressEvent, 
+	               supercedes: DEFAULT_CONFIG.CONTEXT.supercedes
+               }
+           );
+
+	/**
+	* True if the Overlay should be anchored to the center of the viewport.
+	* @config fixedcenter
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(
+               DEFAULT_CONFIG.FIXED_CENTER.key, 
+               {
+                    handler: this.configFixedCenter,
+                    value: DEFAULT_CONFIG.FIXED_CENTER.value, 
+                    validator: DEFAULT_CONFIG.FIXED_CENTER.validator, 
+                    supercedes: DEFAULT_CONFIG.FIXED_CENTER.supercedes
+                }
+            );
+
+	/**
+	* CSS width of the Overlay.
+	* @config width
+	* @type String
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.WIDTH.key,
+	           {
+	               handler: this.configWidth, 
+	               suppressEvent: DEFAULT_CONFIG.WIDTH.suppressEvent, 
+	               supercedes: DEFAULT_CONFIG.WIDTH.supercedes
+               }
+           );
+
+	/**
+	* CSS height of the Overlay.
+	* @config height
+	* @type String
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.HEIGHT.key, 
+	           {
+	               handler: this.configHeight, 
+	               suppressEvent: DEFAULT_CONFIG.HEIGHT.suppressEvent, 
+	               supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
+               }
+           );
+
+	/**
+	* CSS z-index of the Overlay.
+	* @config zIndex
+	* @type Number
+	* @default null
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.ZINDEX.key, 
+	           {
+	               handler: this.configzIndex,
+	               value: DEFAULT_CONFIG.ZINDEX.value
+               }
+           );
+
+	/**
+	* True if the Overlay should be prevented from being positioned out of the viewport.
+	* @config constraintoviewport
+	* @type Boolean
+	* @default false
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, 
+	           {
+	               handler: this.configConstrainToViewport, 
+	               value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value, 
+	               validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator, 
+	               supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
+               }
+           );
+
+	/**
+	* True if the Overlay should have an IFRAME shim (for correcting the select z-index bug in IE6 and below).
+	* @config iframe
+	* @type Boolean
+	* @default true for IE6 and below, false for all others
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.IFRAME.key, 
+	           {
+	               handler: this.configIframe, 
+	               value: DEFAULT_CONFIG.IFRAME.value, 
+	               validator: DEFAULT_CONFIG.IFRAME.validator, 
+	               supercedes: DEFAULT_CONFIG.IFRAME.supercedes
+	           }
+           );
+
+};
+
+/**
+* Moves the Overlay to the specified position. This function is identical to calling this.cfg.setProperty("xy", [x,y]);
+* @method moveTo
+* @param {Number}	x	The Overlay's new x position
+* @param {Number}	y	The Overlay's new y position
+*/
+YAHOO.widget.Overlay.prototype.moveTo = function(x, y) {
+	this.cfg.setProperty("xy",[x,y]);
+};
+
+/**
+* Adds a special CSS class to the Overlay when Mac/Gecko is in use, to work around a Gecko bug where
+* scrollbars cannot be hidden. See https://bugzilla.mozilla.org/show_bug.cgi?id=187435
+* @method hideMacGeckoScrollbars
+*/
+YAHOO.widget.Overlay.prototype.hideMacGeckoScrollbars = function() {
+	YAHOO.util.Dom.removeClass(this.element, "show-scrollbars");
+	YAHOO.util.Dom.addClass(this.element, "hide-scrollbars");
+};
+
+/**
+* Removes a special CSS class from the Overlay when Mac/Gecko is in use, to work around a Gecko bug where
+* scrollbars cannot be hidden. See https://bugzilla.mozilla.org/show_bug.cgi?id=187435
+* @method showMacGeckoScrollbars
+*/
+YAHOO.widget.Overlay.prototype.showMacGeckoScrollbars = function() {
+	YAHOO.util.Dom.removeClass(this.element, "hide-scrollbars");
+	YAHOO.util.Dom.addClass(this.element, "show-scrollbars");
+};
+
+// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* The default event handler fired when the "visible" property is changed. This method is responsible for firing showEvent and hideEvent.
+* @method configVisible
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configVisible = function(type, args, obj) {
+	var visible = args[0];
+	var currentVis = YAHOO.util.Dom.getStyle(this.element, "visibility");
+
+	if (currentVis == "inherit") {
+		var e = this.element.parentNode;
+		while (e.nodeType != 9 && e.nodeType != 11) {
+			currentVis = YAHOO.util.Dom.getStyle(e, "visibility");
+			if (currentVis != "inherit") { break; }
+			e = e.parentNode;
+		}
+		if (currentVis == "inherit") {
+			currentVis = "visible";
+		}
+	}
+
+	var effect = this.cfg.getProperty("effect");
+
+	var effectInstances = [];
+	if (effect) {
+		if (effect instanceof Array) {
+			for (var i=0;i<effect.length;i++) {
+				var eff = effect[i];
+				effectInstances[effectInstances.length] = eff.effect(this, eff.duration);
+			}
+		} else {
+			effectInstances[effectInstances.length] = effect.effect(this, effect.duration);
+		}
+	}
+
+	var isMacGecko = (this.platform == "mac" && this.browser == "gecko");
+
+	if (visible) { // Show
+		if (isMacGecko) {
+			this.showMacGeckoScrollbars();
+		}
+
+		if (effect) { // Animate in
+			if (visible) { // Animate in if not showing
+				if (currentVis != "visible" || currentVis === "") {
+					this.beforeShowEvent.fire();
+					for (var j=0;j<effectInstances.length;j++) {
+						var ei = effectInstances[j];
+						if (j === 0 && ! YAHOO.util.Config.alreadySubscribed(ei.animateInCompleteEvent,this.showEvent.fire,this.showEvent)) {
+							ei.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true); // Delegate showEvent until end of animateInComplete
+						}
+						ei.animateIn();
+					}
+				}
+			}
+		} else { // Show
+			if (currentVis != "visible" || currentVis === "") {
+				this.beforeShowEvent.fire();
+				YAHOO.util.Dom.setStyle(this.element, "visibility", "visible");
+				this.cfg.refireEvent("iframe");
+				this.showEvent.fire();
+			}
+		}
+
+	} else { // Hide
+		if (isMacGecko) {
+			this.hideMacGeckoScrollbars();
+		}
+
+		if (effect) { // Animate out if showing
+			if (currentVis == "visible") {
+				this.beforeHideEvent.fire();
+				for (var k=0;k<effectInstances.length;k++) {
+					var h = effectInstances[k];
+					if (k === 0 && ! YAHOO.util.Config.alreadySubscribed(h.animateOutCompleteEvent,this.hideEvent.fire,this.hideEvent)) {
+						h.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true); // Delegate hideEvent until end of animateOutComplete
+					}
+					h.animateOut();
+				}
+			} else if (currentVis === "") {
+				YAHOO.util.Dom.setStyle(this.element, "visibility", "hidden");
+			}
+		} else { // Simple hide
+			if (currentVis == "visible" || currentVis === "") {
+				this.beforeHideEvent.fire();
+				YAHOO.util.Dom.setStyle(this.element, "visibility", "hidden");
+				this.cfg.refireEvent("iframe");
+				this.hideEvent.fire();
+			}
+		}
+	}
+};
+
+/**
+* Center event handler used for centering on scroll/resize, but only if the Overlay is visible
+* @method doCenterOnDOMEvent
+*/
+YAHOO.widget.Overlay.prototype.doCenterOnDOMEvent = function() {
+	if (this.cfg.getProperty("visible")) {
+		this.center();
+	}
+};
+
+/**
+* The default event handler fired when the "fixedcenter" property is changed.
+* @method configFixedCenter
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configFixedCenter = function(type, args, obj) {
+	var val = args[0];
+
+	if (val) {
+		this.center();
+
+		if (! YAHOO.util.Config.alreadySubscribed(this.beforeShowEvent, this.center, this)) {
+			this.beforeShowEvent.subscribe(this.center, this, true);
+		}
+
+		if (! YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowResizeEvent, this.doCenterOnDOMEvent, this)) {
+			YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.doCenterOnDOMEvent, this, true);
+		}
+
+		if (! YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowScrollEvent, this.doCenterOnDOMEvent, this)) {
+			YAHOO.widget.Overlay.windowScrollEvent.subscribe( this.doCenterOnDOMEvent, this, true);
+		}
+	} else {
+		YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
+		YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
+	}
+};
+
+/**
+* The default event handler fired when the "height" property is changed.
+* @method configHeight
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configHeight = function(type, args, obj) {
+	var height = args[0];
+	var el = this.element;
+	YAHOO.util.Dom.setStyle(el, "height", height);
+	this.cfg.refireEvent("iframe");
+};
+
+/**
+* The default event handler fired when the "width" property is changed.
+* @method configWidth
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configWidth = function(type, args, obj) {
+	var width = args[0];
+	var el = this.element;
+	YAHOO.util.Dom.setStyle(el, "width", width);
+	this.cfg.refireEvent("iframe");
+};
+
+/**
+* The default event handler fired when the "zIndex" property is changed.
+* @method configzIndex
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configzIndex = function(type, args, obj) {
+	var zIndex = args[0];
+
+	var el = this.element;
+
+	if (! zIndex) {
+		zIndex = YAHOO.util.Dom.getStyle(el, "zIndex");
+		if (! zIndex || isNaN(zIndex)) {
+			zIndex = 0;
+		}
+	}
+
+	if (this.iframe) {
+		if (zIndex <= 0) {
+			zIndex = 1;
+		}
+		YAHOO.util.Dom.setStyle(this.iframe, "zIndex", (zIndex-1));
+	}
+
+	YAHOO.util.Dom.setStyle(el, "zIndex", zIndex);
+	this.cfg.setProperty("zIndex", zIndex, true);
+};
+
+/**
+* The default event handler fired when the "xy" property is changed.
+* @method configXY
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configXY = function(type, args, obj) {
+	var pos = args[0];
+	var x = pos[0];
+	var y = pos[1];
+
+	this.cfg.setProperty("x", x);
+	this.cfg.setProperty("y", y);
+
+	this.beforeMoveEvent.fire([x,y]);
+
+	x = this.cfg.getProperty("x");
+	y = this.cfg.getProperty("y");
+
+
+	this.cfg.refireEvent("iframe");
+	this.moveEvent.fire([x,y]);
+};
+
+/**
+* The default event handler fired when the "x" property is changed.
+* @method configX
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configX = function(type, args, obj) {
+	var x = args[0];
+	var y = this.cfg.getProperty("y");
+
+	this.cfg.setProperty("x", x, true);
+	this.cfg.setProperty("y", y, true);
+
+	this.beforeMoveEvent.fire([x,y]);
+
+	x = this.cfg.getProperty("x");
+	y = this.cfg.getProperty("y");
+
+	YAHOO.util.Dom.setX(this.element, x, true);
+
+	this.cfg.setProperty("xy", [x, y], true);
+
+	this.cfg.refireEvent("iframe");
+	this.moveEvent.fire([x, y]);
+};
+
+/**
+* The default event handler fired when the "y" property is changed.
+* @method configY
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configY = function(type, args, obj) {
+	var x = this.cfg.getProperty("x");
+	var y = args[0];
+
+	this.cfg.setProperty("x", x, true);
+	this.cfg.setProperty("y", y, true);
+
+	this.beforeMoveEvent.fire([x,y]);
+
+	x = this.cfg.getProperty("x");
+	y = this.cfg.getProperty("y");
+
+	YAHOO.util.Dom.setY(this.element, y, true);
+
+	this.cfg.setProperty("xy", [x, y], true);
+
+	this.cfg.refireEvent("iframe");
+	this.moveEvent.fire([x, y]);
+};
+
+/**
+* Shows the iframe shim, if it has been enabled
+* @method showIframe
+*/
+YAHOO.widget.Overlay.prototype.showIframe = function() {
+	if (this.iframe) {
+		this.iframe.style.display = "block";
+	}
+};
+
+/**
+* Hides the iframe shim, if it has been enabled
+* @method hideIframe
+*/
+YAHOO.widget.Overlay.prototype.hideIframe = function() {
+	if (this.iframe) {
+		this.iframe.style.display = "none";
+	}
+};
+
+/**
+* The default event handler fired when the "iframe" property is changed.
+* @method configIframe
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configIframe = function(type, args, obj) {
+
+	var val = args[0];
+
+	if (val) { // IFRAME shim is enabled
+
+		if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, this.showIframe, this)) {
+			this.showEvent.subscribe(this.showIframe, this, true);
+		}
+		if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, this.hideIframe, this)) {
+			this.hideEvent.subscribe(this.hideIframe, this, true);
+		}
+
+		var x = this.cfg.getProperty("x");
+		var y = this.cfg.getProperty("y");
+
+		if (! x || ! y) {
+			this.syncPosition();
+			x = this.cfg.getProperty("x");
+			y = this.cfg.getProperty("y");
+		}
+
+
+		if (! isNaN(x) && ! isNaN(y)) {
+			if (! this.iframe) {
+				this.iframe = document.createElement("iframe");
+				if (this.isSecure) {
+					this.iframe.src = YAHOO.widget.Overlay.IFRAME_SRC;
+				}
+
+				var parent = this.element.parentNode;
+				if (parent) {
+					parent.appendChild(this.iframe);
+				} else {
+					document.body.appendChild(this.iframe);
+				}
+
+				YAHOO.util.Dom.setStyle(this.iframe, "position", "absolute");
+				YAHOO.util.Dom.setStyle(this.iframe, "border", "none");
+				YAHOO.util.Dom.setStyle(this.iframe, "margin", "0");
+				YAHOO.util.Dom.setStyle(this.iframe, "padding", "0");
+				YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
+				if (this.cfg.getProperty("visible")) {
+					this.showIframe();
+				} else {
+					this.hideIframe();
+				}
+			}
+
+			var iframeDisplay = YAHOO.util.Dom.getStyle(this.iframe, "display");
+
+			if (iframeDisplay == "none") {
+				this.iframe.style.display = "block";
+			}
+
+			YAHOO.util.Dom.setXY(this.iframe, [x,y]);
+
+			var width = this.element.clientWidth;
+			var height = this.element.clientHeight;
+
+			YAHOO.util.Dom.setStyle(this.iframe, "width", (width+2) + "px");
+			YAHOO.util.Dom.setStyle(this.iframe, "height", (height+2) + "px");
+
+			if (iframeDisplay == "none") {
+				this.iframe.style.display = "none";
+			}
+		}
+	} else {
+		if (this.iframe) {
+			this.iframe.style.display = "none";
+		}
+		this.showEvent.unsubscribe(this.showIframe, this);
+		this.hideEvent.unsubscribe(this.hideIframe, this);
+	}
+};
+
+
+/**
+* The default event handler fired when the "constraintoviewport" property is changed.
+* @method configConstrainToViewport
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configConstrainToViewport = function(type, args, obj) {
+	var val = args[0];
+	if (val) {
+		if (! YAHOO.util.Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
+			this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
+		}
+	} else {
+		this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
+	}
+};
+
+/**
+* The default event handler fired when the "context" property is changed.
+* @method configContext
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.configContext = function(type, args, obj) {
+	var contextArgs = args[0];
+
+	if (contextArgs) {
+		var contextEl = contextArgs[0];
+		var elementMagnetCorner = contextArgs[1];
+		var contextMagnetCorner = contextArgs[2];
+
+		if (contextEl) {
+			if (typeof contextEl == "string") {
+				this.cfg.setProperty("context", [document.getElementById(contextEl),elementMagnetCorner,contextMagnetCorner], true);
+			}
+
+			if (elementMagnetCorner && contextMagnetCorner) {
+				this.align(elementMagnetCorner, contextMagnetCorner);
+			}
+		}
+	}
+};
+
+
+// END BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* Aligns the Overlay to its context element using the specified corner points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, and BOTTOM_RIGHT.
+* @method align
+* @param {String} elementAlign		The String representing the corner of the Overlay that should be aligned to the context element
+* @param {String} contextAlign		The corner of the context element that the elementAlign corner should stick to.
+*/
+YAHOO.widget.Overlay.prototype.align = function(elementAlign, contextAlign) {
+	var contextArgs = this.cfg.getProperty("context");
+	if (contextArgs) {
+		var context = contextArgs[0];
+
+		var element = this.element;
+		var me = this;
+
+		if (! elementAlign) {
+			elementAlign = contextArgs[1];
+		}
+
+		if (! contextAlign) {
+			contextAlign = contextArgs[2];
+		}
+
+		if (element && context) {
+			var contextRegion = YAHOO.util.Dom.getRegion(context);
+
+			var doAlign = function(v,h) {
+				switch (elementAlign) {
+					case YAHOO.widget.Overlay.TOP_LEFT:
+						me.moveTo(h,v);
+						break;
+					case YAHOO.widget.Overlay.TOP_RIGHT:
+						me.moveTo(h-element.offsetWidth,v);
+						break;
+					case YAHOO.widget.Overlay.BOTTOM_LEFT:
+						me.moveTo(h,v-element.offsetHeight);
+						break;
+					case YAHOO.widget.Overlay.BOTTOM_RIGHT:
+						me.moveTo(h-element.offsetWidth,v-element.offsetHeight);
+						break;
+				}
+			};
+
+			switch (contextAlign) {
+				case YAHOO.widget.Overlay.TOP_LEFT:
+					doAlign(contextRegion.top, contextRegion.left);
+					break;
+				case YAHOO.widget.Overlay.TOP_RIGHT:
+					doAlign(contextRegion.top, contextRegion.right);
+					break;
+				case YAHOO.widget.Overlay.BOTTOM_LEFT:
+					doAlign(contextRegion.bottom, contextRegion.left);
+					break;
+				case YAHOO.widget.Overlay.BOTTOM_RIGHT:
+					doAlign(contextRegion.bottom, contextRegion.right);
+					break;
+			}
+		}
+	}
+};
+
+/**
+* The default event handler executed when the moveEvent is fired, if the "constraintoviewport" is set to true.
+* @method enforceConstraints
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Overlay.prototype.enforceConstraints = function(type, args, obj) {
+	var pos = args[0];
+
+	var x = pos[0];
+	var y = pos[1];
+
+	var offsetHeight = this.element.offsetHeight;
+	var offsetWidth = this.element.offsetWidth;
+
+	var viewPortWidth = YAHOO.util.Dom.getViewportWidth();
+	var viewPortHeight = YAHOO.util.Dom.getViewportHeight();
+
+	var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+	var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+
+	var topConstraint = scrollY + 10;
+	var leftConstraint = scrollX + 10;
+	var bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10;
+	var rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;
+
+	if (x < leftConstraint) {
+		x = leftConstraint;
+	} else if (x > rightConstraint) {
+		x = rightConstraint;
+	}
+
+	if (y < topConstraint) {
+		y = topConstraint;
+	} else if (y > bottomConstraint) {
+		y = bottomConstraint;
+	}
+
+	this.cfg.setProperty("x", x, true);
+	this.cfg.setProperty("y", y, true);
+	this.cfg.setProperty("xy", [x,y], true);
+};
+
+/**
+* Centers the container in the viewport.
+* @method center
+*/
+YAHOO.widget.Overlay.prototype.center = function() {
+	var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+	var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+
+	var viewPortWidth = YAHOO.util.Dom.getClientWidth();
+	var viewPortHeight = YAHOO.util.Dom.getClientHeight();
+
+	var elementWidth = this.element.offsetWidth;
+	var elementHeight = this.element.offsetHeight;
+
+	var x = (viewPortWidth / 2) - (elementWidth / 2) + scrollX;
+	var y = (viewPortHeight / 2) - (elementHeight / 2) + scrollY;
+
+	this.cfg.setProperty("xy", [parseInt(x, 10), parseInt(y, 10)]);
+
+	this.cfg.refireEvent("iframe");
+};
+
+/**
+* Synchronizes the Panel's "xy", "x", and "y" properties with the Panel's position in the DOM. This is primarily used to update position information during drag & drop.
+* @method syncPosition
+*/
+YAHOO.widget.Overlay.prototype.syncPosition = function() {
+	var pos = YAHOO.util.Dom.getXY(this.element);
+	this.cfg.setProperty("x", pos[0], true);
+	this.cfg.setProperty("y", pos[1], true);
+	this.cfg.setProperty("xy", pos, true);
+};
+
+/**
+* Event handler fired when the resize monitor element is resized.
+* @method onDomResize
+* @param {DOMEvent} e	The resize DOM event
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.Overlay.prototype.onDomResize = function(e, obj) {
+	YAHOO.widget.Overlay.superclass.onDomResize.call(this, e, obj);
+	var me = this;
+	setTimeout(function() {
+		me.syncPosition();
+		me.cfg.refireEvent("iframe");
+		me.cfg.refireEvent("context");
+	}, 0);
+};
+
+/**
+* Removes the Overlay element from the DOM and sets all child elements to null.
+* @method destroy
+*/
+YAHOO.widget.Overlay.prototype.destroy = function() {
+	if (this.iframe) {
+		this.iframe.parentNode.removeChild(this.iframe);
+	}
+
+	this.iframe = null;
+
+	YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
+	YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
+
+	YAHOO.widget.Overlay.superclass.destroy.call(this);
+};
+
+/**
+* Returns a String representation of the object.
+* @method toString
+* @return {String} The string representation of the Overlay.
+*/
+YAHOO.widget.Overlay.prototype.toString = function() {
+	return "Overlay " + this.id;
+};
+
+/**
+* A singleton CustomEvent used for reacting to the DOM event for window scroll
+* @event YAHOO.widget.Overlay.windowScrollEvent
+*/
+YAHOO.widget.Overlay.windowScrollEvent = new YAHOO.util.CustomEvent("windowScroll");
+
+/**
+* A singleton CustomEvent used for reacting to the DOM event for window resize
+* @event YAHOO.widget.Overlay.windowResizeEvent
+*/
+YAHOO.widget.Overlay.windowResizeEvent = new YAHOO.util.CustomEvent("windowResize");
+
+/**
+* The DOM event handler used to fire the CustomEvent for window scroll
+* @method YAHOO.widget.Overlay.windowScrollHandler
+* @static
+* @param {DOMEvent} e The DOM scroll event
+*/
+YAHOO.widget.Overlay.windowScrollHandler = function(e) {
+	if (YAHOO.widget.Module.prototype.browser == "ie" || YAHOO.widget.Module.prototype.browser == "ie7") {
+		if (! window.scrollEnd) {
+			window.scrollEnd = -1;
+		}
+		clearTimeout(window.scrollEnd);
+		window.scrollEnd = setTimeout(function() { YAHOO.widget.Overlay.windowScrollEvent.fire(); }, 1);
+	} else {
+		YAHOO.widget.Overlay.windowScrollEvent.fire();
+	}
+};
+
+/**
+* The DOM event handler used to fire the CustomEvent for window resize
+* @method YAHOO.widget.Overlay.windowResizeHandler
+* @static
+* @param {DOMEvent} e The DOM resize event
+*/
+YAHOO.widget.Overlay.windowResizeHandler = function(e) {
+	if (YAHOO.widget.Module.prototype.browser == "ie" || YAHOO.widget.Module.prototype.browser == "ie7") {
+		if (! window.resizeEnd) {
+			window.resizeEnd = -1;
+		}
+		clearTimeout(window.resizeEnd);
+		window.resizeEnd = setTimeout(function() { YAHOO.widget.Overlay.windowResizeEvent.fire(); }, 100);
+	} else {
+		YAHOO.widget.Overlay.windowResizeEvent.fire();
+	}
+};
+
+/**
+* A boolean that indicated whether the window resize and scroll events have already been subscribed to.
+* @property YAHOO.widget.Overlay._initialized
+* @private
+* @type Boolean
+*/
+YAHOO.widget.Overlay._initialized = null;
+
+if (YAHOO.widget.Overlay._initialized === null) {
+	YAHOO.util.Event.addListener(window, "scroll", YAHOO.widget.Overlay.windowScrollHandler);
+	YAHOO.util.Event.addListener(window, "resize", YAHOO.widget.Overlay.windowResizeHandler);
+
+	YAHOO.widget.Overlay._initialized = true;
+}
+/**
+* OverlayManager is used for maintaining the focus status of multiple Overlays.* @namespace YAHOO.widget
+* @namespace YAHOO.widget
+* @class OverlayManager
+* @constructor
+* @param {Array}	overlays	Optional. A collection of Overlays to register with the manager.
+* @param {Object}	userConfig		The object literal representing the user configuration of the OverlayManager
+*/
+YAHOO.widget.OverlayManager = function(userConfig) {
+	this.init(userConfig);
+};
+
+/**
+* The CSS class representing a focused Overlay
+* @property YAHOO.widget.OverlayManager.CSS_FOCUSED
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.OverlayManager.CSS_FOCUSED = "focused";
+
+YAHOO.widget.OverlayManager.prototype = {
+	/**
+	* The class's constructor function
+	* @property contructor
+	* @type Function
+	*/
+	constructor : YAHOO.widget.OverlayManager,
+
+	/**
+	* The array of Overlays that are currently registered
+	* @property overlays
+	* @type YAHOO.widget.Overlay[]
+	*/
+	overlays : null,
+
+	/**
+	* Initializes the default configuration of the OverlayManager
+	* @method initDefaultConfig
+	*/
+	initDefaultConfig : function() {
+		/**
+		* The collection of registered Overlays in use by the OverlayManager
+		* @config overlays
+		* @type YAHOO.widget.Overlay[]
+		* @default null
+		*/
+		this.cfg.addProperty("overlays", { suppressEvent:true } );
+
+		/**
+		* The default DOM event that should be used to focus an Overlay
+		* @config focusevent
+		* @type String
+		* @default "mousedown"
+		*/
+		this.cfg.addProperty("focusevent", { value:"mousedown" } );
+	},
+
+	/**
+	* Initializes the OverlayManager
+	* @method init
+	* @param {YAHOO.widget.Overlay[]}	overlays	Optional. A collection of Overlays to register with the manager.
+	* @param {Object}	userConfig		The object literal representing the user configuration of the OverlayManager
+	*/
+	init : function(userConfig) {
+		/**
+		* The OverlayManager's Config object used for monitoring configuration properties.
+		* @property cfg
+		* @type YAHOO.util.Config
+		*/
+		this.cfg = new YAHOO.util.Config(this);
+
+		this.initDefaultConfig();
+
+		if (userConfig) {
+			this.cfg.applyConfig(userConfig, true);
+		}
+		this.cfg.fireQueue();
+
+		/**
+		* The currently activated Overlay
+		* @property activeOverlay
+		* @private
+		* @type YAHOO.widget.Overlay
+		*/
+		var activeOverlay = null;
+
+		/**
+		* Returns the currently focused Overlay
+		* @method getActive
+		* @return {YAHOO.widget.Overlay}	The currently focused Overlay
+		*/
+		this.getActive = function() {
+			return activeOverlay;
+		};
+
+		/**
+		* Focuses the specified Overlay
+		* @method focus
+		* @param {YAHOO.widget.Overlay} overlay	The Overlay to focus
+		* @param {String} overlay	The id of the Overlay to focus
+		*/
+		this.focus = function(overlay) {
+
+			var o = this.find(overlay);
+
+			if (o) {
+
+                if (activeOverlay != o) {
+
+                    if(activeOverlay) {
+    
+                        activeOverlay.blur();
+    
+                    }
+    
+                    activeOverlay = o;
+    
+                    YAHOO.util.Dom.addClass(activeOverlay.element, YAHOO.widget.OverlayManager.CSS_FOCUSED);
+    
+                    this.overlays.sort(this.compareZIndexDesc);
+    
+                    var topZIndex = YAHOO.util.Dom.getStyle(this.overlays[0].element, "zIndex");
+    
+                    if (! isNaN(topZIndex) && this.overlays[0] != overlay) {
+    
+                        activeOverlay.cfg.setProperty("zIndex", (parseInt(topZIndex, 10) + 2));
+    
+                    }
+    
+                    this.overlays.sort(this.compareZIndexDesc);
+    
+                    o.focusEvent.fire();
+                
+                }
+
+			}
+
+		};
+
+		/**
+		* Removes the specified Overlay from the manager
+		* @method remove
+		* @param {YAHOO.widget.Overlay}	overlay	The Overlay to remove
+		* @param {String} overlay	The id of the Overlay to remove
+		*/
+		this.remove = function(overlay) {
+			var o = this.find(overlay);
+			if (o) {
+				var originalZ = YAHOO.util.Dom.getStyle(o.element, "zIndex");
+				o.cfg.setProperty("zIndex", -1000, true);
+				this.overlays.sort(this.compareZIndexDesc);
+				this.overlays = this.overlays.slice(0, this.overlays.length-1);
+				o.cfg.setProperty("zIndex", originalZ, true);
+
+				o.cfg.setProperty("manager", null);
+				o.focusEvent = null;
+				o.blurEvent = null;
+				o.focus = null;
+				o.blur = null;
+			}
+		};
+
+		/**
+		* Removes focus from all registered Overlays in the manager
+		* @method blurAll
+		*/
+		this.blurAll = function() {
+			for (var o=0;o<this.overlays.length;o++) {
+                this.overlays[o].blur();
+			}
+		};
+
+
+        this._onOverlayBlur = function(p_sType, p_aArgs) {
+            activeOverlay = null;
+        };
+
+
+		var overlays = this.cfg.getProperty("overlays");
+
+		if (! this.overlays) {
+			this.overlays = [];
+		}
+
+		if (overlays) {
+			this.register(overlays);
+			this.overlays.sort(this.compareZIndexDesc);
+		}
+	},
+
+	/**
+	* Registers an Overlay or an array of Overlays with the manager. Upon registration, the Overlay receives functions for focus and blur, along with CustomEvents for each.
+	* @method register
+	* @param {YAHOO.widget.Overlay}	overlay		An Overlay to register with the manager.
+	* @param {YAHOO.widget.Overlay[]}	overlay		An array of Overlays to register with the manager.
+	* @return	{Boolean}	True if any Overlays are registered.
+	*/
+	register : function(overlay) {
+		if (overlay instanceof YAHOO.widget.Overlay) {
+			overlay.cfg.addProperty("manager", { value:this } );
+
+			overlay.focusEvent = new YAHOO.util.CustomEvent("focus", overlay);
+			overlay.blurEvent = new YAHOO.util.CustomEvent("blur", overlay);
+
+			var mgr=this;
+
+			overlay.focus = function() {
+				mgr.focus(this);
+			};
+
+			overlay.blur = function() {
+                if(mgr.getActive() == this) {
+                    YAHOO.util.Dom.removeClass(this.element, YAHOO.widget.OverlayManager.CSS_FOCUSED);
+                    this.blurEvent.fire();
+				}
+			};
+
+            overlay.blurEvent.subscribe(mgr._onOverlayBlur);
+
+			var focusOnDomEvent = function(e,obj) {
+				overlay.focus();
+			};
+
+			var focusevent = this.cfg.getProperty("focusevent");
+			YAHOO.util.Event.addListener(overlay.element,focusevent,focusOnDomEvent,this,true);
+
+			var zIndex = YAHOO.util.Dom.getStyle(overlay.element, "zIndex");
+			if (! isNaN(zIndex)) {
+				overlay.cfg.setProperty("zIndex", parseInt(zIndex, 10));
+			} else {
+				overlay.cfg.setProperty("zIndex", 0);
+			}
+
+			this.overlays.push(overlay);
+			return true;
+		} else if (overlay instanceof Array) {
+			var regcount = 0;
+			for (var i=0;i<overlay.length;i++) {
+				if (this.register(overlay[i])) {
+					regcount++;
+				}
+			}
+			if (regcount > 0) {
+				return true;
+			}
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	* Attempts to locate an Overlay by instance or ID.
+	* @method find
+	* @param {YAHOO.widget.Overlay}	overlay		An Overlay to locate within the manager
+	* @param {String}	overlay		An Overlay id to locate within the manager
+	* @return	{YAHOO.widget.Overlay}	The requested Overlay, if found, or null if it cannot be located.
+	*/
+	find : function(overlay) {
+		if (overlay instanceof YAHOO.widget.Overlay) {
+			for (var o=0;o<this.overlays.length;o++) {
+				if (this.overlays[o] == overlay) {
+					return this.overlays[o];
+				}
+			}
+		} else if (typeof overlay == "string") {
+			for (var p=0;p<this.overlays.length;p++) {
+				if (this.overlays[p].id == overlay) {
+					return this.overlays[p];
+				}
+			}
+		}
+		return null;
+	},
+
+	/**
+	* Used for sorting the manager's Overlays by z-index.
+	* @method compareZIndexDesc
+	* @private
+	* @return {Number}	0, 1, or -1, depending on where the Overlay should fall in the stacking order.
+	*/
+	compareZIndexDesc : function(o1, o2) {
+		var zIndex1 = o1.cfg.getProperty("zIndex");
+		var zIndex2 = o2.cfg.getProperty("zIndex");
+
+		if (zIndex1 > zIndex2) {
+			return -1;
+		} else if (zIndex1 < zIndex2) {
+			return 1;
+		} else {
+			return 0;
+		}
+	},
+
+	/**
+	* Shows all Overlays in the manager.
+	* @method showAll
+	*/
+	showAll : function() {
+		for (var o=0;o<this.overlays.length;o++) {
+			this.overlays[o].show();
+		}
+	},
+
+	/**
+	* Hides all Overlays in the manager.
+	* @method hideAll
+	*/
+	hideAll : function() {
+		for (var o=0;o<this.overlays.length;o++) {
+			this.overlays[o].hide();
+		}
+	},
+
+	/**
+	* Returns a string representation of the object.
+	* @method toString
+	* @return {String}	The string representation of the OverlayManager
+	*/
+	toString : function() {
+		return "OverlayManager";
+	}
+
+};
+/**
+* Tooltip is an implementation of Overlay that behaves like an OS tooltip, displaying when the user mouses over a particular element, and disappearing on mouse out.
+* @namespace YAHOO.widget
+* @class Tooltip
+* @extends YAHOO.widget.Overlay
+* @constructor
+* @param {String}	el	The element ID representing the Tooltip <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Tooltip
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Overlay. See configuration documentation for more details.
+*/
+YAHOO.widget.Tooltip = function(el, userConfig) {
+	YAHOO.widget.Tooltip.superclass.constructor.call(this, el, userConfig);
+};
+
+YAHOO.extend(YAHOO.widget.Tooltip, YAHOO.widget.Overlay);
+
+/**
+* Constant representing the Tooltip CSS class
+* @property YAHOO.widget.Tooltip.CSS_TOOLTIP
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Tooltip.CSS_TOOLTIP = "yui-tt";
+
+/**
+* Constant representing the Tooltip's configuration properties
+* @property YAHOO.widget.Tooltip._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Tooltip._DEFAULT_CONFIG = {
+
+    "PREVENT_OVERLAP": { 
+        key: "preventoverlap", 
+        value:true, 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["x","y","xy"] 
+    },
+
+    "SHOW_DELAY": { 
+        key: "showdelay", 
+        value:200, 
+        validator:YAHOO.lang.isNumber 
+    }, 
+
+    "AUTO_DISMISS_DELAY": { 
+        key: "autodismissdelay", 
+        value:5000, 
+        validator:YAHOO.lang.isNumber 
+    }, 
+
+    "HIDE_DELAY": { 
+        key: "hidedelay", 
+        value:250, 
+        validator:YAHOO.lang.isNumber 
+    }, 
+
+    "TEXT": { 
+        key: "text", 
+        suppressEvent:true 
+    }, 
+
+    "CONTAINER": { 
+        key: "container"
+    }
+
+};
+
+/**
+* The Tooltip initialization method. This method is automatically called by the constructor. A Tooltip is automatically rendered by the init method, and it also is set to be invisible by default, and constrained to viewport by default as well.
+* @method init
+* @param {String}	el	The element ID representing the Tooltip <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Tooltip
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Tooltip. See configuration documentation for more details.
+*/
+YAHOO.widget.Tooltip.prototype.init = function(el, userConfig) {
+
+	if (document.readyState && document.readyState != "complete") {
+		var deferredInit = function() {
+			this.init(el, userConfig);
+		};
+		YAHOO.util.Event.addListener(window, "load", deferredInit, this, true);
+	} else {
+		YAHOO.widget.Tooltip.superclass.init.call(this, el);
+
+		this.beforeInitEvent.fire(YAHOO.widget.Tooltip);
+
+		YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Tooltip.CSS_TOOLTIP);
+
+		if (userConfig) {
+			this.cfg.applyConfig(userConfig, true);
+		}
+
+		this.cfg.queueProperty("visible",false);
+		this.cfg.queueProperty("constraintoviewport",true);
+
+		this.setBody("");
+		this.render(this.cfg.getProperty("container"));
+
+		this.initEvent.fire(YAHOO.widget.Tooltip);
+	}
+};
+
+/**
+* Initializes the class's configurable properties which can be changed using the Overlay's Config object (cfg).
+* @method initDefaultConfig
+*/
+YAHOO.widget.Tooltip.prototype.initDefaultConfig = function() {
+	YAHOO.widget.Tooltip.superclass.initDefaultConfig.call(this);
+
+    var DEFAULT_CONFIG = YAHOO.widget.Tooltip._DEFAULT_CONFIG;
+
+	/**
+	* Specifies whether the Tooltip should be kept from overlapping its context element.
+	* @config preventoverlap
+	* @type Boolean
+	* @default true
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.PREVENT_OVERLAP.key,
+	           {
+	               value: DEFAULT_CONFIG.PREVENT_OVERLAP.value, 
+	               validator: DEFAULT_CONFIG.PREVENT_OVERLAP.validator, 
+	               supercedes: DEFAULT_CONFIG.PREVENT_OVERLAP.supercedes
+               }
+           );
+
+	/**
+	* The number of milliseconds to wait before showing a Tooltip on mouseover.
+	* @config showdelay
+	* @type Number
+	* @default 200
+	*/
+	this.cfg.addProperty(
+                DEFAULT_CONFIG.SHOW_DELAY.key,
+                {
+                    handler: this.configShowDelay,
+                    value: 200, 
+                    validator: DEFAULT_CONFIG.SHOW_DELAY.validator
+                }
+          );
+
+	/**
+	* The number of milliseconds to wait before automatically dismissing a Tooltip after the mouse has been resting on the context element.
+	* @config autodismissdelay
+	* @type Number
+	* @default 5000
+	*/
+	this.cfg.addProperty(
+                DEFAULT_CONFIG.AUTO_DISMISS_DELAY.key,	
+                {
+                    handler: this.configAutoDismissDelay,
+                    value: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.value,
+                    validator: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.validator
+                }
+            );
+
+	/**
+	* The number of milliseconds to wait before hiding a Tooltip on mouseover.
+	* @config hidedelay
+	* @type Number
+	* @default 250
+	*/
+	this.cfg.addProperty(
+                DEFAULT_CONFIG.HIDE_DELAY.key,
+                {
+                    handler: this.configHideDelay,
+                    value: DEFAULT_CONFIG.HIDE_DELAY.value, 
+                    validator: DEFAULT_CONFIG.HIDE_DELAY.validator
+                }
+            );
+
+	/**
+	* Specifies the Tooltip's text.
+	* @config text
+	* @type String
+	* @default null
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.TEXT.key,
+                {
+                    handler: this.configText,
+                    suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent
+                }
+            );
+
+	/**
+	* Specifies the container element that the Tooltip's markup should be rendered into.
+	* @config container
+	* @type HTMLElement/String
+	* @default document.body
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.CONTAINER.key,
+                {
+                    handler: this.configContainer,
+                    value: document.body
+                }
+            );
+
+	/**
+	* Specifies the element or elements that the Tooltip should be anchored to on mouseover.
+	* @config context
+	* @type HTMLElement[]/String[]
+	* @default null
+	*/	
+
+};
+
+// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* The default event handler fired when the "text" property is changed.
+* @method configText
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Tooltip.prototype.configText = function(type, args, obj) {
+	var text = args[0];
+	if (text) {
+		this.setBody(text);
+	}
+};
+
+/**
+* The default event handler fired when the "container" property is changed.
+* @method configContainer
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Tooltip.prototype.configContainer = function(type, args, obj) {
+	var container = args[0];
+	if (typeof container == 'string') {
+		this.cfg.setProperty("container", document.getElementById(container), true);
+	}
+};
+
+/**
+* @method _removeEventListeners
+* @description Removes all of the DOM event handlers from the HTML element(s) 
+* that trigger the display of the tooltip.
+* @protected
+*/
+YAHOO.widget.Tooltip.prototype._removeEventListeners = function() {
+
+    var aElements = this._context;
+    
+    if (aElements) {
+
+        var nElements = aElements.length;
+        
+        if (nElements > 0) {
+        
+            var i = nElements - 1,
+                oElement;
+            
+            do {
+
+                oElement = aElements[i];
+
+                YAHOO.util.Event.removeListener(oElement, "mouseover", this.onContextMouseOver);
+                YAHOO.util.Event.removeListener(oElement, "mousemove", this.onContextMouseMove);
+                YAHOO.util.Event.removeListener(oElement, "mouseout", this.onContextMouseOut);
+            
+            }
+            while(i--);
+        
+        }
+
+    }
+
+};
+
+/**
+* The default event handler fired when the "context" property is changed.
+* @method configContext
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Tooltip.prototype.configContext = function(type, args, obj) {
+	var context = args[0];
+	if (context) {
+
+		// Normalize parameter into an array
+		if (! (context instanceof Array)) {
+			if (typeof context == "string") {
+				this.cfg.setProperty("context", [document.getElementById(context)], true);
+			} else { // Assuming this is an element
+				this.cfg.setProperty("context", [context], true);
+			}
+			context = this.cfg.getProperty("context");
+		}
+
+
+		// Remove any existing mouseover/mouseout listeners
+        this._removeEventListeners();
+
+		// Add mouseover/mouseout listeners to context elements
+		this._context = context;
+
+        var aElements = this._context;
+        
+        if (aElements) {
+    
+            var nElements = aElements.length;
+            
+            if (nElements > 0) {
+            
+                var i = nElements - 1,
+                    oElement;
+                
+                do {
+    
+                    oElement = aElements[i];
+    
+                    YAHOO.util.Event.addListener(oElement, "mouseover", this.onContextMouseOver, this);
+                    YAHOO.util.Event.addListener(oElement, "mousemove", this.onContextMouseMove, this);
+                    YAHOO.util.Event.addListener(oElement, "mouseout", this.onContextMouseOut, this);
+                
+                }
+                while(i--);
+            
+            }
+    
+        }
+
+	}
+};
+
+// END BUILT-IN PROPERTY EVENT HANDLERS //
+
+// BEGIN BUILT-IN DOM EVENT HANDLERS //
+
+/**
+* The default event handler fired when the user moves the mouse while over the context element.
+* @method onContextMouseMove
+* @param {DOMEvent} e	The current DOM event
+* @param {Object}	obj	The object argument
+*/
+YAHOO.widget.Tooltip.prototype.onContextMouseMove = function(e, obj) {
+	obj.pageX = YAHOO.util.Event.getPageX(e);
+	obj.pageY = YAHOO.util.Event.getPageY(e);
+
+};
+
+/**
+* The default event handler fired when the user mouses over the context element.
+* @method onContextMouseOver
+* @param {DOMEvent} e	The current DOM event
+* @param {Object}	obj	The object argument
+*/
+YAHOO.widget.Tooltip.prototype.onContextMouseOver = function(e, obj) {
+
+	if (obj.hideProcId) {
+		clearTimeout(obj.hideProcId);
+		obj.hideProcId = null;
+	}
+
+	var context = this;
+	YAHOO.util.Event.addListener(context, "mousemove", obj.onContextMouseMove, obj);
+
+	if (context.title) {
+		obj._tempTitle = context.title;
+		context.title = "";
+	}
+
+	/**
+	* The unique process ID associated with the thread responsible for showing the Tooltip.
+	* @type int
+	*/
+	obj.showProcId = obj.doShow(e, context);
+};
+
+/**
+* The default event handler fired when the user mouses out of the context element.
+* @method onContextMouseOut
+* @param {DOMEvent} e	The current DOM event
+* @param {Object}	obj	The object argument
+*/
+YAHOO.widget.Tooltip.prototype.onContextMouseOut = function(e, obj) {
+	var el = this;
+
+	if (obj._tempTitle) {
+		el.title = obj._tempTitle;
+		obj._tempTitle = null;
+	}
+
+	if (obj.showProcId) {
+		clearTimeout(obj.showProcId);
+		obj.showProcId = null;
+	}
+
+	if (obj.hideProcId) {
+		clearTimeout(obj.hideProcId);
+		obj.hideProcId = null;
+	}
+
+
+	obj.hideProcId = setTimeout(function() {
+				obj.hide();
+				}, obj.cfg.getProperty("hidedelay"));
+};
+
+// END BUILT-IN DOM EVENT HANDLERS //
+
+/**
+* Processes the showing of the Tooltip by setting the timeout delay and offset of the Tooltip.
+* @method doShow
+* @param {DOMEvent} e	The current DOM event
+* @return {Number}	The process ID of the timeout function associated with doShow
+*/
+YAHOO.widget.Tooltip.prototype.doShow = function(e, context) {
+
+	var yOffset = 25;
+	if (this.browser == "opera" && context.tagName && context.tagName.toUpperCase() == "A") {
+		yOffset += 12;
+	}
+
+	var me = this;
+	return setTimeout(
+		function() {
+			if (me._tempTitle) {
+				me.setBody(me._tempTitle);
+			} else {
+				me.cfg.refireEvent("text");
+			}
+
+			me.moveTo(me.pageX, me.pageY + yOffset);
+			if (me.cfg.getProperty("preventoverlap")) {
+				me.preventOverlap(me.pageX, me.pageY);
+			}
+
+			YAHOO.util.Event.removeListener(context, "mousemove", me.onContextMouseMove);
+
+			me.show();
+			me.hideProcId = me.doHide();
+		},
+	this.cfg.getProperty("showdelay"));
+};
+
+/**
+* Sets the timeout for the auto-dismiss delay, which by default is 5 seconds, meaning that a tooltip will automatically dismiss itself after 5 seconds of being displayed.
+* @method doHide
+*/
+YAHOO.widget.Tooltip.prototype.doHide = function() {
+	var me = this;
+	return setTimeout(
+		function() {
+			me.hide();
+		},
+		this.cfg.getProperty("autodismissdelay"));
+};
+
+/**
+* Fired when the Tooltip is moved, this event handler is used to prevent the Tooltip from overlapping with its context element.
+* @method preventOverlay
+* @param {Number} pageX	The x coordinate position of the mouse pointer
+* @param {Number} pageY	The y coordinate position of the mouse pointer
+*/
+YAHOO.widget.Tooltip.prototype.preventOverlap = function(pageX, pageY) {
+
+	var height = this.element.offsetHeight;
+
+	var elementRegion = YAHOO.util.Dom.getRegion(this.element);
+
+	elementRegion.top -= 5;
+	elementRegion.left -= 5;
+	elementRegion.right += 5;
+	elementRegion.bottom += 5;
+
+	var mousePoint = new YAHOO.util.Point(pageX, pageY);
+
+
+	if (elementRegion.contains(mousePoint)) {
+		this.cfg.setProperty("y", (pageY-height-5));
+	}
+};
+
+/**
+* Removes the Tooltip element from the DOM and sets all child elements to null.
+* @method destroy
+*/
+YAHOO.widget.Tooltip.prototype.destroy = function() {
+
+    // Remove any existing mouseover/mouseout listeners
+    this._removeEventListeners();
+
+    YAHOO.widget.Tooltip.superclass.destroy.call(this);  
+
+};
+
+/**
+* Returns a string representation of the object.
+* @method toString
+* @return {String}	The string representation of the Tooltip
+*/
+YAHOO.widget.Tooltip.prototype.toString = function() {
+	return "Tooltip " + this.id;
+};
+/**
+* Panel is an implementation of Overlay that behaves like an OS window, with a draggable header and an optional close icon at the top right.
+* @namespace YAHOO.widget
+* @class Panel
+* @extends YAHOO.widget.Overlay
+* @constructor
+* @param {String}	el	The element ID representing the Panel <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Panel
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Panel. See configuration documentation for more details.
+*/
+YAHOO.widget.Panel = function(el, userConfig) {
+	YAHOO.widget.Panel.superclass.constructor.call(this, el, userConfig);
+};
+
+YAHOO.extend(YAHOO.widget.Panel, YAHOO.widget.Overlay);
+
+/**
+* Constant representing the default CSS class used for a Panel
+* @property YAHOO.widget.Panel.CSS_PANEL
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Panel.CSS_PANEL = "yui-panel";
+
+/**
+* Constant representing the default CSS class used for a Panel's wrapping container
+* @property YAHOO.widget.Panel.CSS_PANEL_CONTAINER
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Panel.CSS_PANEL_CONTAINER = "yui-panel-container";
+
+/**
+* Constant representing the name of the Panel's events
+* @property YAHOO.widget.Panel._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Panel._EVENT_TYPES = {
+
+	"SHOW_MASK": "showMask",
+	"HIDE_MASK": "hideMask",
+	"DRAG": "drag"
+
+};
+
+/**
+* Constant representing the Panel's configuration properties
+* @property YAHOO.widget.Panel._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Panel._DEFAULT_CONFIG = {
+
+    "CLOSE": { 
+        key: "close", 
+        value:true, 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["visible"] 
+    },
+
+    "DRAGGABLE": { 
+        key: "draggable", 
+        value:(YAHOO.util.DD ? true : false), 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["visible"]  
+    },
+
+    "UNDERLAY": { 
+        key: "underlay", 
+        value:"shadow", 
+        supercedes:["visible"] 
+    },
+
+    "MODAL": { 
+        key: "modal", 
+        value:false, 
+        validator:YAHOO.lang.isBoolean, 
+        supercedes:["visible"] 
+    },
+
+    "KEY_LISTENERS": { 
+        key: "keylisteners", 
+        suppressEvent:true, 
+        supercedes:["visible"] 
+    }
+
+};
+
+/**
+* The Overlay initialization method, which is executed for Overlay and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
+* @method init
+* @param {String}	el	The element ID representing the Overlay <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Overlay
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Overlay. See configuration documentation for more details.
+*/
+YAHOO.widget.Panel.prototype.init = function(el, userConfig) {
+	YAHOO.widget.Panel.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
+
+	this.beforeInitEvent.fire(YAHOO.widget.Panel);
+
+	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Panel.CSS_PANEL);
+
+	this.buildWrapper();
+
+	if (userConfig) {
+		this.cfg.applyConfig(userConfig, true);
+	}
+
+	this.beforeRenderEvent.subscribe(function() {
+		var draggable = this.cfg.getProperty("draggable");
+		if (draggable) {
+			if (! this.header) {
+				this.setHeader("&#160;");
+			}
+		}
+	}, this, true);
+
+
+    this.renderEvent.subscribe(function() {
+
+        /*
+            If no value for the "width" configuration property was specified, 
+            set it to the offsetWidth. If the "width" is not set, then in IE 
+            you can only drag the panel when you put the cursor on the
+            header's text.
+        */
+
+        var sWidth = this.cfg.getProperty("width");
+        
+        if(!sWidth) {
+
+            this.cfg.setProperty("width", (this.element.offsetWidth + "px"));
+        
+        }
+    
+    });
+
+
+	var me = this;
+
+	var doBlur = function() {
+		this.blur();
+	};
+
+	this.showMaskEvent.subscribe(function() {
+
+		var checkFocusable = function(el) {
+
+            var sTagName = el.tagName.toUpperCase(),
+                bFocusable = false;
+            
+            switch(sTagName) {
+            
+                case "A":
+                case "BUTTON":
+                case "SELECT":
+                case "TEXTAREA":
+
+                    if (! YAHOO.util.Dom.isAncestor(me.element, el)) {
+                        YAHOO.util.Event.addListener(el, "focus", doBlur, el, true);
+                        bFocusable = true;
+                    }
+
+                break;
+
+                case "INPUT":
+
+                    if (el.type != "hidden" && ! YAHOO.util.Dom.isAncestor(me.element, el)) {
+
+                        YAHOO.util.Event.addListener(el, "focus", doBlur, el, true);
+                        bFocusable = true;
+
+                    }
+
+                break;
+            
+            }
+
+            return bFocusable;
+
+		};
+
+		this.focusableElements = YAHOO.util.Dom.getElementsBy(checkFocusable);
+	}, this, true);
+
+	this.hideMaskEvent.subscribe(function() {
+		for (var i=0;i<this.focusableElements.length;i++) {
+			var el2 = this.focusableElements[i];
+			YAHOO.util.Event.removeListener(el2, "focus", doBlur);
+		}
+	}, this, true);
+
+	this.beforeShowEvent.subscribe(function() {
+		this.cfg.refireEvent("underlay");
+	}, this, true);
+	this.initEvent.fire(YAHOO.widget.Panel);
+};
+
+/**
+* Initializes the custom events for Module which are fired automatically at appropriate times by the Module class.
+*/
+YAHOO.widget.Panel.prototype.initEvents = function() {
+	YAHOO.widget.Panel.superclass.initEvents.call(this);
+
+    var EVENT_TYPES = YAHOO.widget.Panel._EVENT_TYPES;
+
+	/**
+	* CustomEvent fired after the modality mask is shown
+	* @event showMaskEvent
+	*/
+	this.showMaskEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.SHOW_MASK, this);
+
+	/**
+	* CustomEvent fired after the modality mask is hidden
+	* @event hideMaskEvent
+	*/
+	this.hideMaskEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.HIDE_MASK, this);
+
+	/**
+	* CustomEvent when the Panel is dragged
+	* @event dragEvent
+	*/
+	this.dragEvent = new YAHOO.util.CustomEvent(EVENT_TYPES.DRAG, this);
+};
+
+/**
+* Initializes the class's configurable properties which can be changed using the Panel's Config object (cfg).
+* @method initDefaultConfig
+*/
+YAHOO.widget.Panel.prototype.initDefaultConfig = function() {
+	YAHOO.widget.Panel.superclass.initDefaultConfig.call(this);
+
+    // Add panel config properties //
+
+    var DEFAULT_CONFIG = YAHOO.widget.Panel._DEFAULT_CONFIG;
+
+	/**
+	* True if the Panel should display a "close" button
+	* @config close
+	* @type Boolean
+	* @default true
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.CLOSE.key,
+                { 
+                    handler: this.configClose, 
+                    value: DEFAULT_CONFIG.CLOSE.value, 
+                    validator: DEFAULT_CONFIG.CLOSE.validator, 
+                    supercedes: DEFAULT_CONFIG.CLOSE.supercedes
+                } 
+            );
+
+	/**
+	* True if the Panel should be draggable.  Default value is "true" if the Drag and Drop utility is included, otherwise it is "false."
+	* @config draggable
+	* @type Boolean
+	* @default true
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.DRAGGABLE.key, 
+                { 
+                    handler: this.configDraggable, 
+                    value: DEFAULT_CONFIG.DRAGGABLE.value, 
+                    validator: DEFAULT_CONFIG.DRAGGABLE.validator, 
+                    supercedes: DEFAULT_CONFIG.DRAGGABLE.supercedes 
+                } 
+            );
+
+	/**
+	* Sets the type of underlay to display for the Panel. Valid values are "shadow", "matte", and "none".
+	* @config underlay
+	* @type String
+	* @default shadow
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.UNDERLAY.key, 
+                { 
+                    handler: this.configUnderlay, 
+                    value: DEFAULT_CONFIG.UNDERLAY.value, 
+                    supercedes: DEFAULT_CONFIG.UNDERLAY.supercedes
+                } 
+            );
+
+	/**
+	* True if the Panel should be displayed in a modal fashion, automatically creating a transparent mask over the document that will not be removed until the Panel is dismissed.
+	* @config modal
+	* @type Boolean
+	* @default false
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.MODAL.key,
+                { 
+                    handler: this.configModal, 
+                    value: DEFAULT_CONFIG.MODAL.value,
+                    validator: DEFAULT_CONFIG.MODAL.validator, 
+                    supercedes: DEFAULT_CONFIG.MODAL.supercedes 
+                } 
+            );
+
+	/**
+	* A KeyListener (or array of KeyListeners) that will be enabled when the Panel is shown, and disabled when the Panel is hidden.
+	* @config keylisteners
+	* @type YAHOO.util.KeyListener[]
+	* @default null
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.KEY_LISTENERS.key, 
+                { 
+                    handler: this.configKeyListeners, 
+                    suppressEvent: DEFAULT_CONFIG.KEY_LISTENERS.suppressEvent, 
+                    supercedes: DEFAULT_CONFIG.KEY_LISTENERS.supercedes
+                } 
+            );
+
+};
+
+// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* The default event handler fired when the "close" property is changed. The method controls the appending or hiding of the close icon at the top right of the Panel.
+* @method configClose
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configClose = function(type, args, obj) {
+	var val = args[0];
+
+	var doHide = function(e, obj) {
+		obj.hide();
+	};
+
+	if (val) {
+		if (! this.close) {
+			this.close = document.createElement("span");
+			YAHOO.util.Dom.addClass(this.close, "container-close");
+			this.close.innerHTML = "&#160;";
+			this.innerElement.appendChild(this.close);
+			YAHOO.util.Event.addListener(this.close, "click", doHide, this);
+		} else {
+			this.close.style.display = "block";
+		}
+	} else {
+		if (this.close) {
+			this.close.style.display = "none";
+		}
+	}
+};
+
+/**
+* The default event handler fired when the "draggable" property is changed.
+* @method configDraggable
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configDraggable = function(type, args, obj) {
+
+	var val = args[0];
+	if (val) {
+
+        if (!YAHOO.util.DD) {
+    
+
+            this.cfg.setProperty("draggable", false);
+    
+            return;
+        
+        }
+
+		if (this.header) {
+			YAHOO.util.Dom.setStyle(this.header,"cursor","move");
+			this.registerDragDrop();
+		}
+	} else {
+		if (this.dd) {
+			this.dd.unreg();
+		}
+		if (this.header) {
+			YAHOO.util.Dom.setStyle(this.header,"cursor","auto");
+		}
+	}
+};
+
+/**
+* The default event handler fired when the "underlay" property is changed.
+* @method configUnderlay
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configUnderlay = function(type, args, obj) {
+	var val = args[0];
+
+	switch (val.toLowerCase()) {
+		case "shadow":
+			YAHOO.util.Dom.removeClass(this.element, "matte");
+			YAHOO.util.Dom.addClass(this.element, "shadow");
+
+			if (! this.underlay) { // create if not already in DOM
+				this.underlay = document.createElement("div");
+				this.underlay.className = "underlay";
+				this.underlay.innerHTML = "&#160;";
+				this.element.appendChild(this.underlay);
+			}
+
+			this.sizeUnderlay();
+			break;
+		case "matte":
+			YAHOO.util.Dom.removeClass(this.element, "shadow");
+			YAHOO.util.Dom.addClass(this.element, "matte");
+			break;
+		default:
+			YAHOO.util.Dom.removeClass(this.element, "shadow");
+			YAHOO.util.Dom.removeClass(this.element, "matte");
+			break;
+	}
+};
+
+/**
+* The default event handler fired when the "modal" property is changed. This handler subscribes or unsubscribes to the show and hide events to handle the display or hide of the modality mask.
+* @method configModal
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configModal = function(type, args, obj) {
+	var modal = args[0];
+
+	if (modal) {
+		this.buildMask();
+
+		if (! YAHOO.util.Config.alreadySubscribed( this.beforeShowEvent, this.showMask, this ) ) {
+			this.beforeShowEvent.subscribe(this.showMask, this, true);
+		}
+		if (! YAHOO.util.Config.alreadySubscribed( this.hideEvent, this.hideMask, this) ) {
+			this.hideEvent.subscribe(this.hideMask, this, true);
+		}
+		if (! YAHOO.util.Config.alreadySubscribed( YAHOO.widget.Overlay.windowResizeEvent, this.sizeMask, this ) ) {
+			YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.sizeMask, this, true);
+		}
+		if (! YAHOO.util.Config.alreadySubscribed( this.destroyEvent, this.removeMask, this) ) {
+			this.destroyEvent.subscribe(this.removeMask, this, true);
+		}
+
+		this.cfg.refireEvent("zIndex");
+	} else {
+		this.beforeShowEvent.unsubscribe(this.showMask, this);
+		this.hideEvent.unsubscribe(this.hideMask, this);
+		YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.sizeMask, this);
+		this.destroyEvent.unsubscribe(this.removeMask, this);
+	}
+};
+
+/**
+* Removes the modality mask.
+* @method removeMask
+*/
+YAHOO.widget.Panel.prototype.removeMask = function() {
+
+    var oMask = this.mask;
+
+    if(oMask) {
+    
+        /*
+            Hide the mask before destroying it to ensure that DOM
+            event handlers on focusable elements get removed.
+        */
+
+        this.hideMask();
+    
+        var oParentNode = oMask.parentNode;
+
+        if(oParentNode) {
+
+            oParentNode.removeChild(oMask);
+
+        }
+
+        this.mask = null;
+    }
+    
+};
+
+/**
+* The default event handler fired when the "keylisteners" property is changed.
+* @method configKeyListeners
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configKeyListeners = function(type, args, obj) {
+	var listeners = args[0];
+
+	if (listeners) {
+		if (listeners instanceof Array) {
+			for (var i=0;i<listeners.length;i++) {
+				var listener = listeners[i];
+
+				if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, listener.enable, listener)) {
+					this.showEvent.subscribe(listener.enable, listener, true);
+				}
+				if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, listener.disable, listener)) {
+					this.hideEvent.subscribe(listener.disable, listener, true);
+					this.destroyEvent.subscribe(listener.disable, listener, true);
+				}
+			}
+		} else {
+			if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, listeners.enable, listeners)) {
+				this.showEvent.subscribe(listeners.enable, listeners, true);
+			}
+			if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, listeners.disable, listeners)) {
+				this.hideEvent.subscribe(listeners.disable, listeners, true);
+				this.destroyEvent.subscribe(listeners.disable, listeners, true);
+			}
+		}
+	}
+};
+
+/**
+* The default event handler fired when the "height" property is changed.
+* @method configHeight
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configHeight = function(type, args, obj) {
+	var height = args[0];
+	var el = this.innerElement;
+	YAHOO.util.Dom.setStyle(el, "height", height);
+	this.cfg.refireEvent("underlay");
+	this.cfg.refireEvent("iframe");
+};
+
+/**
+* The default event handler fired when the "width" property is changed.
+* @method configWidth
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configWidth = function(type, args, obj) {
+	var width = args[0];
+	var el = this.innerElement;
+	YAHOO.util.Dom.setStyle(el, "width", width);
+	this.cfg.refireEvent("underlay");
+	this.cfg.refireEvent("iframe");
+};
+
+/**
+* The default event handler fired when the "zIndex" property is changed.
+* @method configzIndex
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Panel.prototype.configzIndex = function(type, args, obj) {
+	YAHOO.widget.Panel.superclass.configzIndex.call(this, type, args, obj);
+
+	var maskZ = 0;
+	var currentZ = YAHOO.util.Dom.getStyle(this.element, "zIndex");
+
+	if (this.mask) {
+		if (! currentZ || isNaN(currentZ)) {
+			currentZ = 0;
+		}
+
+		if (currentZ === 0) {
+			this.cfg.setProperty("zIndex", 1);
+		} else {
+			maskZ = currentZ - 1;
+			YAHOO.util.Dom.setStyle(this.mask, "zIndex", maskZ);
+		}
+
+	}
+};
+
+// END BUILT-IN PROPERTY EVENT HANDLERS //
+
+
+/**
+* Builds the wrapping container around the Panel that is used for positioning the shadow and matte underlays. The container element is assigned to a  local instance variable called container, and the element is reinserted inside of it.
+* @method buildWrapper
+*/
+YAHOO.widget.Panel.prototype.buildWrapper = function() {
+	var elementParent = this.element.parentNode;
+	var originalElement = this.element;
+
+	var wrapper = document.createElement("div");
+	wrapper.className = YAHOO.widget.Panel.CSS_PANEL_CONTAINER;
+	wrapper.id = originalElement.id + "_c";
+
+	if (elementParent) {
+		elementParent.insertBefore(wrapper, originalElement);
+	}
+
+	wrapper.appendChild(originalElement);
+
+	this.element = wrapper;
+	this.innerElement = originalElement;
+
+	YAHOO.util.Dom.setStyle(this.innerElement, "visibility", "inherit");
+};
+
+/**
+* Adjusts the size of the shadow based on the size of the element.
+* @method sizeUnderlay
+*/
+YAHOO.widget.Panel.prototype.sizeUnderlay = function() {
+	if (this.underlay && this.browser != "gecko" && this.browser != "safari") {
+		this.underlay.style.width = this.innerElement.offsetWidth + "px";
+		this.underlay.style.height = this.innerElement.offsetHeight + "px";
+	}
+};
+
+/**
+* Event handler fired when the resize monitor element is resized.
+* @method onDomResize
+* @param {DOMEvent} e	The resize DOM event
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.Panel.prototype.onDomResize = function(e, obj) {
+	YAHOO.widget.Panel.superclass.onDomResize.call(this, e, obj);
+	var me = this;
+	setTimeout(function() {
+		me.sizeUnderlay();
+	}, 0);
+};
+
+/**
+* Registers the Panel's header for drag & drop capability.
+* @method registerDragDrop
+*/
+YAHOO.widget.Panel.prototype.registerDragDrop = function() {
+	if (this.header) {
+
+        if(!YAHOO.util.DD) {
+
+
+            return;
+        
+        }
+
+		this.dd = new YAHOO.util.DD(this.element.id, this.id);
+
+		if (! this.header.id) {
+			this.header.id = this.id + "_h";
+		}
+
+		var me = this;
+
+		this.dd.startDrag = function() {
+
+			if (me.browser == "ie") {
+				YAHOO.util.Dom.addClass(me.element,"drag");
+			}
+
+			if (me.cfg.getProperty("constraintoviewport")) {
+				var offsetHeight = me.element.offsetHeight;
+				var offsetWidth = me.element.offsetWidth;
+
+				var viewPortWidth = YAHOO.util.Dom.getViewportWidth();
+				var viewPortHeight = YAHOO.util.Dom.getViewportHeight();
+
+				var scrollX = window.scrollX || document.documentElement.scrollLeft;
+				var scrollY = window.scrollY || document.documentElement.scrollTop;
+
+				var topConstraint = scrollY + 10;
+				var leftConstraint = scrollX + 10;
+				var bottomConstraint = scrollY + viewPortHeight - offsetHeight - 10;
+				var rightConstraint = scrollX + viewPortWidth - offsetWidth - 10;
+
+				this.minX = leftConstraint;
+				this.maxX = rightConstraint;
+				this.constrainX = true;
+
+				this.minY = topConstraint;
+				this.maxY = bottomConstraint;
+				this.constrainY = true;
+			} else {
+				this.constrainX = false;
+				this.constrainY = false;
+			}
+
+			me.dragEvent.fire("startDrag", arguments);
+		};
+
+		this.dd.onDrag = function() {
+			me.syncPosition();
+			me.cfg.refireEvent("iframe");
+			if (this.platform == "mac" && this.browser == "gecko") {
+				this.showMacGeckoScrollbars();
+			}
+
+			me.dragEvent.fire("onDrag", arguments);
+		};
+
+		this.dd.endDrag = function() {
+			if (me.browser == "ie") {
+				YAHOO.util.Dom.removeClass(me.element,"drag");
+			}
+
+			me.dragEvent.fire("endDrag", arguments);
+		};
+
+		this.dd.setHandleElId(this.header.id);
+		this.dd.addInvalidHandleType("INPUT");
+		this.dd.addInvalidHandleType("SELECT");
+		this.dd.addInvalidHandleType("TEXTAREA");
+	}
+};
+
+/**
+* Builds the mask that is laid over the document when the Panel is configured to be modal.
+* @method buildMask
+*/
+YAHOO.widget.Panel.prototype.buildMask = function() {
+	if (! this.mask) {
+		this.mask = document.createElement("div");
+		this.mask.id = this.id + "_mask";
+		this.mask.className = "mask";
+		this.mask.innerHTML = "&#160;";
+
+		var maskClick = function(e, obj) {
+			YAHOO.util.Event.stopEvent(e);
+		};
+
+		var firstChild = document.body.firstChild;
+		if (firstChild)	{
+			document.body.insertBefore(this.mask, document.body.firstChild);
+		} else {
+			document.body.appendChild(this.mask);
+		}
+	}
+};
+
+/**
+* Hides the modality mask.
+* @method hideMask
+*/
+YAHOO.widget.Panel.prototype.hideMask = function() {
+	if (this.cfg.getProperty("modal") && this.mask) {
+		this.mask.style.display = "none";
+		this.hideMaskEvent.fire();
+		YAHOO.util.Dom.removeClass(document.body, "masked");
+	}
+};
+
+/**
+* Shows the modality mask.
+* @method showMask
+*/
+YAHOO.widget.Panel.prototype.showMask = function() {
+	if (this.cfg.getProperty("modal") && this.mask) {
+		YAHOO.util.Dom.addClass(document.body, "masked");
+		this.sizeMask();
+		this.mask.style.display = "block";
+		this.showMaskEvent.fire();
+	}
+};
+
+/**
+* Sets the size of the modality mask to cover the entire scrollable area of the document
+* @method sizeMask
+*/
+YAHOO.widget.Panel.prototype.sizeMask = function() {
+	if (this.mask) {
+		this.mask.style.height = YAHOO.util.Dom.getDocumentHeight()+"px";
+		this.mask.style.width = YAHOO.util.Dom.getDocumentWidth()+"px";
+	}
+};
+
+/**
+* Renders the Panel by inserting the elements that are not already in the main Panel into their correct places. Optionally appends the Panel to the specified node prior to the render's execution. NOTE: For Panels without existing markup, the appendToNode argument is REQUIRED. If this argument is ommitted and the current element is not present in the document, the function will return false, indicating that the render was a failure.
+* @method render
+* @param {String}	appendToNode	The element id to which the Module should be appended to prior to rendering <em>OR</em>
+* @param {HTMLElement}	appendToNode	The element to which the Module should be appended to prior to rendering
+* @return {boolean} Success or failure of the render
+*/
+YAHOO.widget.Panel.prototype.render = function(appendToNode) {
+	return YAHOO.widget.Panel.superclass.render.call(this, appendToNode, this.innerElement);
+};
+
+/**
+* Removes the Panel element from the DOM and sets all child elements to null.
+* @method destroy
+*/
+YAHOO.widget.Panel.prototype.destroy = function() {
+
+    YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.sizeMask, this);
+
+    if(this.close) {
+    
+        YAHOO.util.Event.purgeElement(this.close);
+
+    }
+
+    YAHOO.widget.Panel.superclass.destroy.call(this);  
+
+};
+
+/**
+* Returns a String representation of the object.
+* @method toString
+* @return {String} The string representation of the Panel.
+*/
+YAHOO.widget.Panel.prototype.toString = function() {
+	return "Panel " + this.id;
+};
+/**
+* Dialog is an implementation of Panel that can be used to submit form data. Built-in functionality for buttons with event handlers is included, and button sets can be build dynamically, or the preincluded ones for Submit/Cancel and OK/Cancel can be utilized. Forms can be processed in 3 ways -- via an asynchronous Connection utility call, a simple form POST or GET, or manually.
+* @namespace YAHOO.widget
+* @class Dialog
+* @extends YAHOO.widget.Panel
+* @constructor
+* @param {String}	el	The element ID representing the Dialog <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Dialog
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Dialog. See configuration documentation for more details.
+*/
+YAHOO.widget.Dialog = function(el, userConfig) {
+	YAHOO.widget.Dialog.superclass.constructor.call(this, el, userConfig);
+};
+
+YAHOO.extend(YAHOO.widget.Dialog, YAHOO.widget.Panel);
+
+/**
+* Constant representing the default CSS class used for a Dialog
+* @property YAHOO.widget.Dialog.CSS_DIALOG
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.Dialog.CSS_DIALOG = "yui-dialog";
+
+/**
+* Constant representing the name of the Dialog's events
+* @property YAHOO.widget.Dialog._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Dialog._EVENT_TYPES = {
+
+	"BEFORE_SUBMIT": "beforeSubmit",
+	"SUBMIT": "submit",
+	"MANUAL_SUBMIT": "manualSubmit",
+	"ASYNC_SUBMIT": "asyncSubmit",
+	"FORM_SUBMIT": "formSubmit",
+	"CANCEL": "cancel"
+
+};
+
+/**
+* Constant representing the Dialog's configuration properties
+* @property YAHOO.widget.Dialog._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Dialog._DEFAULT_CONFIG = {
+
+	"POST_METHOD": { 
+	   key: "postmethod", 
+	   value: "async" 
+    },
+
+	"BUTTONS": { 
+	   key: "buttons", 
+	   value: "none" 
+    }
+
+};
+
+/**
+* Initializes the class's configurable properties which can be changed using the Dialog's Config object (cfg).
+* @method initDefaultConfig
+*/
+YAHOO.widget.Dialog.prototype.initDefaultConfig = function() {
+	YAHOO.widget.Dialog.superclass.initDefaultConfig.call(this);
+
+	/**
+	* The internally maintained callback object for use with the Connection utility
+	* @property callback
+	* @type Object
+	*/
+	this.callback = {
+		/**
+		* The function to execute upon success of the Connection submission
+		* @property callback.success
+		* @type Function
+		*/
+		success : null,
+		/**
+		* The function to execute upon failure of the Connection submission
+		* @property callback.failure
+		* @type Function
+		*/
+		failure : null,
+		/**
+		* The arbitraty argument or arguments to pass to the Connection callback functions
+		* @property callback.argument
+		* @type Object
+		*/
+		argument: null
+	};
+
+	// Add form dialog config properties //
+	
+	var DEFAULT_CONFIG = YAHOO.widget.Dialog._DEFAULT_CONFIG;
+	
+	/**
+	* The method to use for posting the Dialog's form. Possible values are "async", "form", and "manual".
+	* @config postmethod
+	* @type String
+	* @default async
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.POST_METHOD.key, 
+                {
+                    handler: this.configPostMethod, 
+                    value: DEFAULT_CONFIG.POST_METHOD.value, 
+                    validator: function(val) {
+                        if (val != "form" && val != "async" && val != "none" && val != "manual") {
+                            return false;
+                        } else {
+                            return true;
+                        }
+                    }
+                }
+            );
+
+	/**
+	* Object literal(s) defining the buttons for the Dialog's footer.
+	* @config buttons
+	* @type Object[]
+	* @default "none"
+	*/
+	this.cfg.addProperty(
+	           DEFAULT_CONFIG.BUTTONS.key,
+	           {
+	               handler: this.configButtons,
+	               value: DEFAULT_CONFIG.BUTTONS.value
+               }
+           );	
+	
+};
+
+/**
+* Initializes the custom events for Dialog which are fired automatically at appropriate times by the Dialog class.
+* @method initEvents
+*/
+YAHOO.widget.Dialog.prototype.initEvents = function() {
+	YAHOO.widget.Dialog.superclass.initEvents.call(this);
+
+    var EVENT_TYPES = YAHOO.widget.Dialog._EVENT_TYPES;
+
+	/**
+	* CustomEvent fired prior to submission
+	* @event beforeSumitEvent
+	*/	
+	this.beforeSubmitEvent	= new YAHOO.util.CustomEvent(EVENT_TYPES.BEFORE_SUBMIT, this);
+	
+	/**
+	* CustomEvent fired after submission
+	* @event submitEvent
+	*/
+	this.submitEvent		= new YAHOO.util.CustomEvent(EVENT_TYPES.SUBMIT, this);
+
+	/**
+	* CustomEvent fired prior to manual submission
+	* @event manualSubmitEvent
+	*/
+	this.manualSubmitEvent	= new YAHOO.util.CustomEvent(EVENT_TYPES.MANUAL_SUBMIT, this);
+
+	/**
+	* CustomEvent fired prior to asynchronous submission
+	* @event asyncSubmitEvent
+	*/	
+	this.asyncSubmitEvent	= new YAHOO.util.CustomEvent(EVENT_TYPES.ASYNC_SUBMIT, this);
+
+	/**
+	* CustomEvent fired prior to form-based submission
+	* @event formSubmitEvent
+	*/
+	this.formSubmitEvent	= new YAHOO.util.CustomEvent(EVENT_TYPES.FORM_SUBMIT, this);
+
+	/**
+	* CustomEvent fired after cancel
+	* @event cancelEvent
+	*/
+	this.cancelEvent		= new YAHOO.util.CustomEvent(EVENT_TYPES.CANCEL, this);
+};
+
+/**
+* The Dialog initialization method, which is executed for Dialog and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
+* @method init
+* @param {String}	el	The element ID representing the Dialog <em>OR</em>
+* @param {HTMLElement}	el	The element representing the Dialog
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this Dialog. See configuration documentation for more details.
+*/
+YAHOO.widget.Dialog.prototype.init = function(el, userConfig) {
+	YAHOO.widget.Dialog.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
+
+	this.beforeInitEvent.fire(YAHOO.widget.Dialog);
+
+	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Dialog.CSS_DIALOG);
+
+	this.cfg.setProperty("visible", false);
+
+	if (userConfig) {
+		this.cfg.applyConfig(userConfig, true);
+	}
+
+	this.showEvent.subscribe(this.focusFirst, this, true);
+	this.beforeHideEvent.subscribe(this.blurButtons, this, true);
+
+	this.beforeRenderEvent.subscribe(function() {
+		var buttonCfg = this.cfg.getProperty("buttons");
+		if (buttonCfg && buttonCfg != "none") {
+			if (! this.footer) {
+				this.setFooter("");
+			}
+		}
+	}, this, true);
+
+	this.initEvent.fire(YAHOO.widget.Dialog);
+};
+
+/**
+* Performs the submission of the Dialog form depending on the value of "postmethod" property.
+* @method doSubmit
+*/
+YAHOO.widget.Dialog.prototype.doSubmit = function() {
+	var pm = this.cfg.getProperty("postmethod");
+	switch (pm) {
+		case "async":
+			var method = this.form.getAttribute("method") || 'POST';
+			method = method.toUpperCase();
+			YAHOO.util.Connect.setForm(this.form);
+			var cObj = YAHOO.util.Connect.asyncRequest(method, this.form.getAttribute("action"), this.callback);
+			this.asyncSubmitEvent.fire();
+			break;
+		case "form":
+			this.form.submit();
+			this.formSubmitEvent.fire();
+			break;
+		case "none":
+		case "manual":
+			this.manualSubmitEvent.fire();
+			break;
+	}
+};
+
+/**
+* @method _onFormKeyDown
+* @description "keydown" event handler for the dialog's form.
+* @protected
+* @param {Event} p_oEvent Object representing the DOM event object passed 
+* back by the event utility (YAHOO.util.Event).
+*/
+YAHOO.widget.Dialog.prototype._onFormKeyDown = function(p_oEvent) {
+
+    var oTarget = YAHOO.util.Event.getTarget(p_oEvent),
+        nCharCode = YAHOO.util.Event.getCharCode(p_oEvent);
+
+    if (
+        nCharCode == 13 && 
+        oTarget.tagName && 
+        oTarget.tagName.toUpperCase() == "INPUT"
+    ) {
+
+        var sType = oTarget.type;
+
+        if(
+            sType == "text" || sType == "password" || sType == "checkbox" || 
+            sType == "radio" || sType == "file"
+        ) {
+
+            // Fire the "click" event on the dialog's default button
+            this.defaultHtmlButton.click();
+        
+        }
+
+    }
+
+};
+
+/**
+* Prepares the Dialog's internal FORM object, creating one if one is not currently present.
+* @method registerForm
+*/
+YAHOO.widget.Dialog.prototype.registerForm = function() {
+	var form = this.element.getElementsByTagName("form")[0];
+
+	if (! form) {
+		var formHTML = "<form name=\"frm_" + this.id + "\" action=\"\"></form>";
+		this.body.innerHTML += formHTML;
+		form = this.element.getElementsByTagName("form")[0];
+	}
+
+	this.firstFormElement = function() {
+		for (var f=0;f<form.elements.length;f++ ) {
+			var el = form.elements[f];
+			if (el.focus && ! el.disabled) {
+				if (el.type && el.type != "hidden") {
+					return el;
+				}
+			}
+		}
+		return null;
+	}();
+
+	this.lastFormElement = function() {
+		for (var f=form.elements.length-1;f>=0;f-- ) {
+			var el = form.elements[f];
+			if (el.focus && ! el.disabled) {
+				if (el.type && el.type != "hidden") {
+					return el;
+				}
+			}
+		}
+		return null;
+	}();
+
+	this.form = form;
+
+    if(this.form && (this.browser == "ie" || this.browser == "ie7" || this.browser == "gecko")) {
+
+        YAHOO.util.Event.addListener(this.form, "keydown", this._onFormKeyDown, null, this);
+    
+    }
+
+
+	if (this.cfg.getProperty("modal") && this.form) {
+
+		var me = this;
+
+		var firstElement = this.firstFormElement || this.firstButton;
+		if (firstElement) {
+			this.preventBackTab = new YAHOO.util.KeyListener(firstElement, { shift:true, keys:9 }, {fn:me.focusLast, scope:me, correctScope:true} );
+			this.showEvent.subscribe(this.preventBackTab.enable, this.preventBackTab, true);
+			this.hideEvent.subscribe(this.preventBackTab.disable, this.preventBackTab, true);
+		}
+
+		var lastElement = this.lastButton || this.lastFormElement;
+		if (lastElement) {
+			this.preventTabOut = new YAHOO.util.KeyListener(lastElement, { shift:false, keys:9 }, {fn:me.focusFirst, scope:me, correctScope:true} );
+			this.showEvent.subscribe(this.preventTabOut.enable, this.preventTabOut, true);
+			this.hideEvent.subscribe(this.preventTabOut.disable, this.preventTabOut, true);
+		}
+	}
+};
+
+// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* The default event handler fired when the "close" property is changed. The method controls the appending or hiding of the close icon at the top right of the Dialog.
+* @method configClose
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Dialog.prototype.configClose = function(type, args, obj) {
+	var val = args[0];
+
+	var doCancel = function(e, obj) {
+		obj.cancel();
+	};
+
+	if (val) {
+		if (! this.close) {
+			this.close = document.createElement("div");
+			YAHOO.util.Dom.addClass(this.close, "container-close");
+
+			this.close.innerHTML = "&#160;";
+			this.innerElement.appendChild(this.close);
+			YAHOO.util.Event.addListener(this.close, "click", doCancel, this);
+		} else {
+			this.close.style.display = "block";
+		}
+	} else {
+		if (this.close) {
+			this.close.style.display = "none";
+		}
+	}
+};
+
+/**
+* The default event handler for the "buttons" configuration property
+* @method configButtons
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Dialog.prototype.configButtons = function(type, args, obj) {
+	var buttons = args[0];
+	if (buttons != "none") {
+		this.buttonSpan = null;
+		this.buttonSpan = document.createElement("span");
+		this.buttonSpan.className = "button-group";
+
+		for (var b=0;b<buttons.length;b++) {
+			var button = buttons[b];
+
+			var htmlButton = document.createElement("button");
+			htmlButton.setAttribute("type", "button");
+
+			if (button.isDefault) {
+				htmlButton.className = "default";
+				this.defaultHtmlButton = htmlButton;
+			}
+
+			htmlButton.appendChild(document.createTextNode(button.text));
+			YAHOO.util.Event.addListener(htmlButton, "click", button.handler, this, true);
+
+			this.buttonSpan.appendChild(htmlButton);
+			button.htmlButton = htmlButton;
+
+			if (b === 0) {
+				this.firstButton = button.htmlButton;
+			}
+
+			if (b == (buttons.length-1)) {
+				this.lastButton = button.htmlButton;
+			}
+
+		}
+
+		this.setFooter(this.buttonSpan);
+
+		this.cfg.refireEvent("iframe");
+		this.cfg.refireEvent("underlay");
+	} else { // Do cleanup
+		if (this.buttonSpan) {
+			if (this.buttonSpan.parentNode) {
+				this.buttonSpan.parentNode.removeChild(this.buttonSpan);
+			}
+
+			this.buttonSpan = null;
+			this.firstButton = null;
+			this.lastButton = null;
+			this.defaultHtmlButton = null;
+		}
+	}
+};
+
+
+/**
+* The default event handler used to focus the first field of the form when the Dialog is shown.
+* @method focusFirst
+*/
+YAHOO.widget.Dialog.prototype.focusFirst = function(type,args,obj) {
+	if (args) {
+		var e = args[1];
+		if (e) {
+			YAHOO.util.Event.stopEvent(e);
+		}
+	}
+
+	if (this.firstFormElement) {
+		this.firstFormElement.focus();
+	} else {
+		this.focusDefaultButton();
+	}
+};
+
+/**
+* Sets the focus to the last button in the button or form element in the Dialog
+* @method focusLast
+*/
+YAHOO.widget.Dialog.prototype.focusLast = function(type,args,obj) {
+	if (args) {
+		var e = args[1];
+		if (e) {
+			YAHOO.util.Event.stopEvent(e);
+		}
+	}
+
+	var buttons = this.cfg.getProperty("buttons");
+	if (buttons && buttons instanceof Array) {
+		this.focusLastButton();
+	} else {
+		if (this.lastFormElement) {
+			this.lastFormElement.focus();
+		}
+	}
+};
+
+/**
+* Sets the focus to the button that is designated as the default. By default, his handler is executed when the show event is fired.
+* @method focusDefaultButton
+*/
+YAHOO.widget.Dialog.prototype.focusDefaultButton = function() {
+	if (this.defaultHtmlButton) {
+		this.defaultHtmlButton.focus();
+	}
+};
+
+/**
+* Blurs all the html buttons
+* @method blurButtons
+*/
+YAHOO.widget.Dialog.prototype.blurButtons = function() {
+	var buttons = this.cfg.getProperty("buttons");
+	if (buttons && buttons instanceof Array) {
+		var html = buttons[0].htmlButton;
+		if (html) {
+			html.blur();
+		}
+	}
+};
+
+/**
+* Sets the focus to the first button in the button list
+* @method focusFirstButton
+*/
+YAHOO.widget.Dialog.prototype.focusFirstButton = function() {
+	var buttons = this.cfg.getProperty("buttons");
+	if (buttons && buttons instanceof Array) {
+		var html = buttons[0].htmlButton;
+		if (html) {
+			html.focus();
+		}
+	}
+};
+
+/**
+* Sets the focus to the first button in the button list
+* @method focusLastButton
+*/
+YAHOO.widget.Dialog.prototype.focusLastButton = function() {
+	var buttons = this.cfg.getProperty("buttons");
+	if (buttons && buttons instanceof Array) {
+		var html = buttons[buttons.length-1].htmlButton;
+		if (html) {
+			html.focus();
+		}
+	}
+};
+
+/**
+* The default event handler for the "postmethod" configuration property
+* @method configPostMethod
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.Dialog.prototype.configPostMethod = function(type, args, obj) {
+	var postmethod = args[0];
+
+	this.registerForm();
+	YAHOO.util.Event.addListener(this.form, "submit", function(e) {
+														YAHOO.util.Event.stopEvent(e);
+														this.submit();
+														this.form.blur();
+													  }, this, true);
+};
+
+// END BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* Built-in function hook for writing a validation function that will be checked for a "true" value prior to a submit. This function, as implemented by default, always returns true, so it should be overridden if validation is necessary.
+* @method validate
+*/
+YAHOO.widget.Dialog.prototype.validate = function() {
+	return true;
+};
+
+/**
+* Executes a submit of the Dialog followed by a hide, if validation is successful.
+* @method submit
+*/
+YAHOO.widget.Dialog.prototype.submit = function() {
+	if (this.validate()) {
+		this.beforeSubmitEvent.fire();
+		this.doSubmit();
+		this.submitEvent.fire();
+		this.hide();
+		return true;
+	} else {
+		return false;
+	}
+};
+
+/**
+* Executes the cancel of the Dialog followed by a hide.
+* @method cancel
+*/
+YAHOO.widget.Dialog.prototype.cancel = function() {
+	this.cancelEvent.fire();
+	this.hide();
+};
+
+/**
+* Returns a JSON-compatible data structure representing the data currently contained in the form.
+* @method getData
+* @return {Object} A JSON object reprsenting the data of the current form.
+*/
+YAHOO.widget.Dialog.prototype.getData = function() {
+
+    var oForm = this.form;
+
+    if(oForm) {
+
+        var aElements = oForm.elements,
+            nTotalElements = aElements.length,
+            oData = {},
+            sName,
+            oElement,
+            nElements;
+
+        for(var i=0; i<nTotalElements; i++) {
+
+            sName = aElements[i].name;
+
+            function isFormElement(p_oElement) {
+            
+                var sTagName = p_oElement.tagName.toUpperCase();
+                
+                return (
+                    (
+                        sTagName == "INPUT" || 
+                        sTagName == "TEXTAREA" || 
+                        sTagName == "SELECT"
+                    ) && 
+                    p_oElement.name == sName
+                );
+
+            }
+
+            /*
+                Using "YAHOO.util.Dom.getElementsBy" to safeguard
+                user from JS errors that result from giving a form field (or 
+                set of fields) the same name as a native method of a form 
+                (like "submit") or a DOM collection (such as the "item" method).
+                Originally tried accessing fields via the "namedItem" method of 
+                the "element" collection, but discovered that it won't return
+                a collection of fields in Gecko.
+            */
+
+            oElement = YAHOO.util.Dom.getElementsBy(isFormElement, "*", oForm);
+            nElements = oElement.length;
+
+            if(nElements > 0) {
+
+                if(nElements == 1) {
+
+                    oElement = oElement[0];
+
+                    var sType = oElement.type,
+                        sTagName = oElement.tagName.toUpperCase();
+
+                    switch(sTagName) {
+
+                        case "INPUT":
+
+                            if(sType == "checkbox") {
+
+                                oData[sName] = oElement.checked;
+
+                            }
+                            else if(sType != "radio") {
+
+                                oData[sName] = oElement.value;
+
+                            }
+
+                        break;
+
+                        case "TEXTAREA":
+
+                            oData[sName] = oElement.value;
+
+                        break;
+
+                        case "SELECT":
+
+                            var aOptions = oElement.options,
+                                nOptions = aOptions.length,
+                                aValues = [],
+                                oOption,
+                                sValue;
+
+
+                            for(var n=0; n<nOptions; n++) {
+
+                                oOption = aOptions[n];
+
+                                if(oOption.selected) {
+
+                                    sValue = oOption.value;
+
+                                    if(!sValue || sValue === "") {
+
+                                        sValue = oOption.text;
+
+                                    }
+
+                                    aValues[aValues.length] = sValue;
+
+                                }
+
+                            }
+
+                            oData[sName] = aValues;
+
+                        break;
+
+                    }
+
+
+                }
+                else {
+
+                    var sType = oElement[0].type;
+
+                    switch(sType) {
+
+                        case "radio":
+
+                            var oRadio;
+
+                            for(var n=0; n<nElements; n++) {
+
+                                oRadio = oElement[n];
+
+                                if(oRadio.checked) {
+
+                                    oData[sName] = oRadio.value;
+                                    break;
+
+                                }
+
+                            }
+
+                        break;
+
+                        case "checkbox":
+
+                            var aValues = [],
+                                oCheckbox;
+
+                            for(var n=0; n<nElements; n++) {
+
+                                oCheckbox = oElement[n];
+
+                                if(oCheckbox.checked) {
+
+                                    aValues[aValues.length] = oCheckbox.value;
+
+                                }
+
+                            }
+
+                            oData[sName] = aValues;
+
+                        break;
+
+                    }
+
+                }
+
+            }
+
+        }
+
+    }
+
+
+    return oData;
+
+};
+
+/**
+* Removes the Panel element from the DOM and sets all child elements to null.
+* @method destroy
+*/
+YAHOO.widget.Dialog.prototype.destroy = function() {
+
+    var Event = YAHOO.util.Event,
+        oForm = this.form,
+        oFooter = this.footer;
+
+    if(oFooter) {
+
+        var aButtons = oFooter.getElementsByTagName("button");
+
+        if(aButtons && aButtons.length > 0) {
+
+            var i = aButtons.length - 1;
+            
+            do {
+            
+                Event.purgeElement(aButtons[i], false, "click");
+            
+            }
+            while(i--);
+        
+        }
+
+    }
+    
+
+    if(oForm) {
+       
+        Event.purgeElement(oForm);
+
+        this.body.removeChild(oForm);
+        
+        this.form = null;
+
+    }
+
+    YAHOO.widget.Dialog.superclass.destroy.call(this);  
+
+};
+
+/**
+* Returns a string representation of the object.
+* @method toString
+* @return {String}	The string representation of the Dialog
+*/
+YAHOO.widget.Dialog.prototype.toString = function() {
+	return "Dialog " + this.id;
+};
+/**
+* SimpleDialog is a simple implementation of Dialog that can be used to submit a single value. Forms can be processed in 3 ways -- via an asynchronous Connection utility call, a simple form POST or GET, or manually.
+* @namespace YAHOO.widget
+* @class SimpleDialog
+* @extends YAHOO.widget.Dialog
+* @constructor
+* @param {String}	el	The element ID representing the SimpleDialog <em>OR</em>
+* @param {HTMLElement}	el	The element representing the SimpleDialog
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this SimpleDialog. See configuration documentation for more details.
+*/
+YAHOO.widget.SimpleDialog = function(el, userConfig) {
+	YAHOO.widget.SimpleDialog.superclass.constructor.call(this, el, userConfig);
+};
+
+YAHOO.extend(YAHOO.widget.SimpleDialog, YAHOO.widget.Dialog);
+
+/**
+* Constant for the standard network icon for a blocking action
+* @property YAHOO.widget.SimpleDialog.ICON_BLOCK
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.ICON_BLOCK = "blckicon";
+
+/**
+* Constant for the standard network icon for alarm
+* @property YAHOO.widget.SimpleDialog.ICON_ALARM
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.ICON_ALARM = "alrticon";
+
+/**
+* Constant for the standard network icon for help
+* @property YAHOO.widget.SimpleDialog.ICON_HELP
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.ICON_HELP  = "hlpicon";
+
+/**
+* Constant for the standard network icon for info
+* @property YAHOO.widget.SimpleDialog.ICON_INFO
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.ICON_INFO  = "infoicon";
+
+/**
+* Constant for the standard network icon for warn
+* @property YAHOO.widget.SimpleDialog.ICON_WARN
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.ICON_WARN  = "warnicon";
+
+/**
+* Constant for the standard network icon for a tip
+* @property YAHOO.widget.SimpleDialog.ICON_TIP
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.ICON_TIP   = "tipicon";
+
+/**
+* Constant representing the default CSS class used for a SimpleDialog
+* @property YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG
+* @static
+* @final
+* @type String
+*/
+YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG = "yui-simple-dialog";
+
+/**
+* Constant representing the SimpleDialog's configuration properties
+* @property YAHOO.widget.SimpleDialog._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.SimpleDialog._DEFAULT_CONFIG = {
+
+    "ICON": { 
+        key: "icon", 
+        value:"none", 
+        suppressEvent:true  
+    },
+
+    "TEXT": { 
+        key: "text", 
+        value:"", 
+        suppressEvent:true, 
+        supercedes:["icon"] 
+    }
+
+};
+
+/**
+* Initializes the class's configurable properties which can be changed using the SimpleDialog's Config object (cfg).
+* @method initDefaultConfig
+*/
+YAHOO.widget.SimpleDialog.prototype.initDefaultConfig = function() {
+	YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);
+
+	// Add dialog config properties //
+
+    var DEFAULT_CONFIG = YAHOO.widget.SimpleDialog._DEFAULT_CONFIG;
+
+	/**
+	* Sets the informational icon for the SimpleDialog
+	* @config icon
+	* @type String
+	* @default "none"
+	*/
+	this.cfg.addProperty(
+                DEFAULT_CONFIG.ICON.key,
+                {
+                    handler: this.configIcon,
+                    value: DEFAULT_CONFIG.ICON.value,
+                    suppressEvent: DEFAULT_CONFIG.ICON.suppressEvent
+                }
+            );
+
+	/**
+	* Sets the text for the SimpleDialog
+	* @config text
+	* @type String
+	* @default ""
+	*/
+    this.cfg.addProperty(
+                DEFAULT_CONFIG.TEXT.key,	
+                { 
+                    handler: this.configText, 
+                    value: DEFAULT_CONFIG.TEXT.value, 
+                    suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent, 
+                    supercedes: DEFAULT_CONFIG.TEXT.supercedes 
+                } 
+            );
+
+};
+
+
+/**
+* The SimpleDialog initialization method, which is executed for SimpleDialog and all of its subclasses. This method is automatically called by the constructor, and  sets up all DOM references for pre-existing markup, and creates required markup if it is not already present.
+* @method init
+* @param {String}	el	The element ID representing the SimpleDialog <em>OR</em>
+* @param {HTMLElement}	el	The element representing the SimpleDialog
+* @param {Object}	userConfig	The configuration object literal containing the configuration that should be set for this SimpleDialog. See configuration documentation for more details.
+*/
+YAHOO.widget.SimpleDialog.prototype.init = function(el, userConfig) {
+	YAHOO.widget.SimpleDialog.superclass.init.call(this, el/*, userConfig*/);  // Note that we don't pass the user config in here yet because we only want it executed once, at the lowest subclass level
+
+	this.beforeInitEvent.fire(YAHOO.widget.SimpleDialog);
+
+	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG);
+
+	this.cfg.queueProperty("postmethod", "manual");
+
+	if (userConfig) {
+		this.cfg.applyConfig(userConfig, true);
+	}
+
+	this.beforeRenderEvent.subscribe(function() {
+		if (! this.body) {
+			this.setBody("");
+		}
+	}, this, true);
+
+	this.initEvent.fire(YAHOO.widget.SimpleDialog);
+
+};
+/**
+* Prepares the SimpleDialog's internal FORM object, creating one if one is not currently present, and adding the value hidden field.
+* @method registerForm
+*/
+YAHOO.widget.SimpleDialog.prototype.registerForm = function() {
+	YAHOO.widget.SimpleDialog.superclass.registerForm.call(this);
+	this.form.innerHTML += "<input type=\"hidden\" name=\"" + this.id + "\" value=\"\"/>";
+};
+
+// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* Fired when the "icon" property is set.
+* @method configIcon
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.SimpleDialog.prototype.configIcon = function(type,args,obj) {
+	var icon = args[0];
+	if (icon && icon != "none") {
+		var iconHTML = "";
+		if (icon.indexOf(".") == -1) {
+			iconHTML = "<span class=\"yui-icon " + icon +"\" >&#160;</span>";
+		} else {
+			iconHTML = "<img src=\"" + this.imageRoot + icon + "\" class=\"yui-icon\" />";
+		}
+		this.body.innerHTML = iconHTML + this.body.innerHTML;
+	}
+};
+
+/**
+* Fired when the "text" property is set.
+* @method configText
+* @param {String} type	The CustomEvent type (usually the property name)
+* @param {Object[]}	args	The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+* @param {Object} obj	The scope object. For configuration handlers, this will usually equal the owner.
+*/
+YAHOO.widget.SimpleDialog.prototype.configText = function(type,args,obj) {
+	var text = args[0];
+	if (text) {
+		this.setBody(text);
+		this.cfg.refireEvent("icon");
+	}
+};
+// END BUILT-IN PROPERTY EVENT HANDLERS //
+
+/**
+* Returns a string representation of the object.
+* @method toString
+* @return {String}	The string representation of the SimpleDialog
+*/
+YAHOO.widget.SimpleDialog.prototype.toString = function() {
+	return "SimpleDialog " + this.id;
+};
+/**
+* ContainerEffect encapsulates animation transitions that are executed when an Overlay is shown or hidden.
+* @namespace YAHOO.widget
+* @class ContainerEffect
+* @constructor
+* @param {YAHOO.widget.Overlay}	overlay		The Overlay that the animation should be associated with
+* @param {Object}	attrIn		The object literal representing the animation arguments to be used for the animate-in transition. The arguments for this literal are: attributes(object, see YAHOO.util.Anim for description), duration(Number), and method(i.e. YAHOO.util.Easing.easeIn).
+* @param {Object}	attrOut		The object literal representing the animation arguments to be used for the animate-out transition. The arguments for this literal are: attributes(object, see YAHOO.util.Anim for description), duration(Number), and method(i.e. YAHOO.util.Easing.easeIn).
+* @param {HTMLElement}	targetElement	Optional. The target element that should be animated during the transition. Defaults to overlay.element.
+* @param {class}	Optional. The animation class to instantiate. Defaults to YAHOO.util.Anim. Other options include YAHOO.util.Motion.
+*/
+YAHOO.widget.ContainerEffect = function(overlay, attrIn, attrOut, targetElement, animClass) {
+	if (! animClass) {
+		animClass = YAHOO.util.Anim;
+	}
+
+	/**
+	* The overlay to animate
+	* @property overlay
+	* @type YAHOO.widget.Overlay
+	*/
+	this.overlay = overlay;
+	/**
+	* The animation attributes to use when transitioning into view
+	* @property attrIn
+	* @type Object
+	*/
+	this.attrIn = attrIn;
+	/**
+	* The animation attributes to use when transitioning out of view
+	* @property attrOut
+	* @type Object
+	*/
+	this.attrOut = attrOut;
+	/**
+	* The target element to be animated
+	* @property targetElement
+	* @type HTMLElement
+	*/
+	this.targetElement = targetElement || overlay.element;
+	/**
+	* The animation class to use for animating the overlay
+	* @property animClass
+	* @type class
+	*/
+	this.animClass = animClass;
+};
+
+/**
+* Initializes the animation classes and events.
+* @method init
+*/
+YAHOO.widget.ContainerEffect.prototype.init = function() {
+	this.beforeAnimateInEvent = new YAHOO.util.CustomEvent("beforeAnimateIn", this);
+	this.beforeAnimateOutEvent = new YAHOO.util.CustomEvent("beforeAnimateOut", this);
+
+	this.animateInCompleteEvent = new YAHOO.util.CustomEvent("animateInComplete", this);
+	this.animateOutCompleteEvent = new YAHOO.util.CustomEvent("animateOutComplete", this);
+
+	this.animIn = new this.animClass(this.targetElement, this.attrIn.attributes, this.attrIn.duration, this.attrIn.method);
+	this.animIn.onStart.subscribe(this.handleStartAnimateIn, this);
+	this.animIn.onTween.subscribe(this.handleTweenAnimateIn, this);
+	this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn, this);
+
+	this.animOut = new this.animClass(this.targetElement, this.attrOut.attributes, this.attrOut.duration, this.attrOut.method);
+	this.animOut.onStart.subscribe(this.handleStartAnimateOut, this);
+	this.animOut.onTween.subscribe(this.handleTweenAnimateOut, this);
+	this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut, this);
+};
+
+/**
+* Triggers the in-animation.
+* @method animateIn
+*/
+YAHOO.widget.ContainerEffect.prototype.animateIn = function() {
+	this.beforeAnimateInEvent.fire();
+	this.animIn.animate();
+};
+
+/**
+* Triggers the out-animation.
+* @method animateOut
+*/
+YAHOO.widget.ContainerEffect.prototype.animateOut = function() {
+	this.beforeAnimateOutEvent.fire();
+	this.animOut.animate();
+};
+
+/**
+* The default onStart handler for the in-animation.
+* @method handleStartAnimateIn
+* @param {String} type	The CustomEvent type
+* @param {Object[]}	args	The CustomEvent arguments
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.ContainerEffect.prototype.handleStartAnimateIn = function(type, args, obj) { };
+/**
+* The default onTween handler for the in-animation.
+* @method handleTweenAnimateIn
+* @param {String} type	The CustomEvent type
+* @param {Object[]}	args	The CustomEvent arguments
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateIn = function(type, args, obj) { };
+/**
+* The default onComplete handler for the in-animation.
+* @method handleCompleteAnimateIn
+* @param {String} type	The CustomEvent type
+* @param {Object[]}	args	The CustomEvent arguments
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateIn = function(type, args, obj) { };
+
+/**
+* The default onStart handler for the out-animation.
+* @method handleStartAnimateOut
+* @param {String} type	The CustomEvent type
+* @param {Object[]}	args	The CustomEvent arguments
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.ContainerEffect.prototype.handleStartAnimateOut = function(type, args, obj) { };
+/**
+* The default onTween handler for the out-animation.
+* @method handleTweenAnimateOut
+* @param {String} type	The CustomEvent type
+* @param {Object[]}	args	The CustomEvent arguments
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateOut = function(type, args, obj) { };
+/**
+* The default onComplete handler for the out-animation.
+* @method handleCompleteAnimateOut
+* @param {String} type	The CustomEvent type
+* @param {Object[]}	args	The CustomEvent arguments
+* @param {Object} obj	The scope object
+*/
+YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateOut = function(type, args, obj) { };
+
+/**
+* Returns a string representation of the object.
+* @method toString
+* @return {String}	The string representation of the ContainerEffect
+*/
+YAHOO.widget.ContainerEffect.prototype.toString = function() {
+	var output = "ContainerEffect";
+	if (this.overlay) {
+		output += " [" + this.overlay.toString() + "]";
+	}
+	return output;
+};
+
+/**
+* A pre-configured ContainerEffect instance that can be used for fading an overlay in and out.
+* @method FADE
+* @static
+* @param {Overlay}	overlay	The Overlay object to animate
+* @param {Number}	dur	The duration of the animation
+* @return {ContainerEffect}	The configured ContainerEffect object
+*/
+YAHOO.widget.ContainerEffect.FADE = function(overlay, dur) {
+	var fade = new YAHOO.widget.ContainerEffect(overlay, { attributes:{opacity: {from:0, to:1}}, duration:dur, method:YAHOO.util.Easing.easeIn }, { attributes:{opacity: {to:0}}, duration:dur, method:YAHOO.util.Easing.easeOut}, overlay.element );
+
+	fade.handleStartAnimateIn = function(type,args,obj) {
+		YAHOO.util.Dom.addClass(obj.overlay.element, "hide-select");
+
+		if (! obj.overlay.underlay) {
+			obj.overlay.cfg.refireEvent("underlay");
+		}
+
+		if (obj.overlay.underlay) {
+			obj.initialUnderlayOpacity = YAHOO.util.Dom.getStyle(obj.overlay.underlay, "opacity");
+			obj.overlay.underlay.style.filter = null;
+		}
+
+		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "visible");
+		YAHOO.util.Dom.setStyle(obj.overlay.element, "opacity", 0);
+	};
+
+	fade.handleCompleteAnimateIn = function(type,args,obj) {
+		YAHOO.util.Dom.removeClass(obj.overlay.element, "hide-select");
+
+		if (obj.overlay.element.style.filter) {
+			obj.overlay.element.style.filter = null;
+		}
+
+		if (obj.overlay.underlay) {
+			YAHOO.util.Dom.setStyle(obj.overlay.underlay, "opacity", obj.initialUnderlayOpacity);
+		}
+
+		obj.overlay.cfg.refireEvent("iframe");
+		obj.animateInCompleteEvent.fire();
+	};
+
+	fade.handleStartAnimateOut = function(type, args, obj) {
+		YAHOO.util.Dom.addClass(obj.overlay.element, "hide-select");
+
+		if (obj.overlay.underlay) {
+			obj.overlay.underlay.style.filter = null;
+		}
+	};
+
+	fade.handleCompleteAnimateOut =  function(type, args, obj) {
+		YAHOO.util.Dom.removeClass(obj.overlay.element, "hide-select");
+		if (obj.overlay.element.style.filter) {
+			obj.overlay.element.style.filter = null;
+		}
+		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "hidden");
+		YAHOO.util.Dom.setStyle(obj.overlay.element, "opacity", 1);
+
+		obj.overlay.cfg.refireEvent("iframe");
+
+		obj.animateOutCompleteEvent.fire();
+	};
+
+	fade.init();
+	return fade;
+};
+
+
+/**
+* A pre-configured ContainerEffect instance that can be used for sliding an overlay in and out.
+* @method SLIDE
+* @static
+* @param {Overlay}	overlay	The Overlay object to animate
+* @param {Number}	dur	The duration of the animation
+* @return {ContainerEffect}	The configured ContainerEffect object
+*/
+YAHOO.widget.ContainerEffect.SLIDE = function(overlay, dur) {
+	var x = overlay.cfg.getProperty("x") || YAHOO.util.Dom.getX(overlay.element);
+	var y = overlay.cfg.getProperty("y") || YAHOO.util.Dom.getY(overlay.element);
+
+	var clientWidth = YAHOO.util.Dom.getClientWidth();
+	var offsetWidth = overlay.element.offsetWidth;
+
+	var slide = new YAHOO.widget.ContainerEffect(overlay, {
+															attributes:{ points: { to:[x, y] } },
+															duration:dur,
+															method:YAHOO.util.Easing.easeIn
+														},
+														{
+															attributes:{ points: { to:[(clientWidth+25), y] } },
+															duration:dur,
+															method:YAHOO.util.Easing.easeOut
+														},
+														overlay.element,
+														YAHOO.util.Motion);
+
+
+	slide.handleStartAnimateIn = function(type,args,obj) {
+		obj.overlay.element.style.left = (-25-offsetWidth) + "px";
+		obj.overlay.element.style.top  = y + "px";
+	};
+
+	slide.handleTweenAnimateIn = function(type, args, obj) {
+
+
+		var pos = YAHOO.util.Dom.getXY(obj.overlay.element);
+
+		var currentX = pos[0];
+		var currentY = pos[1];
+
+		if (YAHOO.util.Dom.getStyle(obj.overlay.element, "visibility") == "hidden" && currentX < x) {
+			YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "visible");
+		}
+
+		obj.overlay.cfg.setProperty("xy", [currentX,currentY], true);
+		obj.overlay.cfg.refireEvent("iframe");
+	};
+
+	slide.handleCompleteAnimateIn = function(type, args, obj) {
+		obj.overlay.cfg.setProperty("xy", [x,y], true);
+		obj.startX = x;
+		obj.startY = y;
+		obj.overlay.cfg.refireEvent("iframe");
+		obj.animateInCompleteEvent.fire();
+	};
+
+	slide.handleStartAnimateOut = function(type, args, obj) {
+		var vw = YAHOO.util.Dom.getViewportWidth();
+
+		var pos = YAHOO.util.Dom.getXY(obj.overlay.element);
+
+		var yso = pos[1];
+
+		var currentTo = obj.animOut.attributes.points.to;
+		obj.animOut.attributes.points.to = [(vw+25), yso];
+	};
+
+	slide.handleTweenAnimateOut = function(type, args, obj) {
+		var pos = YAHOO.util.Dom.getXY(obj.overlay.element);
+
+		var xto = pos[0];
+		var yto = pos[1];
+
+		obj.overlay.cfg.setProperty("xy", [xto,yto], true);
+		obj.overlay.cfg.refireEvent("iframe");
+	};
+
+	slide.handleCompleteAnimateOut = function(type, args, obj) {
+		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "hidden");
+
+		obj.overlay.cfg.setProperty("xy", [x,y]);
+		obj.animateOutCompleteEvent.fire();
+	};
+
+	slide.init();
+	return slide;
+};
+YAHOO.register("container", YAHOO.widget.Module, {version: "2.2.1", build: "193"});

Modified: jifty/branches/virtual-models/share/web/static/js/yui/dom.js
==============================================================================
--- jifty/branches/virtual-models/share/web/static/js/yui/dom.js	(original)
+++ jifty/branches/virtual-models/share/web/static/js/yui/dom.js	Mon May  7 16:28:32 2007
@@ -1,893 +1,923 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.12.1
-*/
-
-/**
- * The dom module provides helper methods for manipulating Dom elements.
- * @module dom
- *
- */
-
-(function() {
-    var Y = YAHOO.util,     // internal shorthand
-        getStyle,           // for load time browser branching
-        setStyle,           // ditto
-        id_counter = 0,     // for use with generateId
-        propertyCache = {}; // for faster hyphen converts
-
-    // brower detection
-    var ua = navigator.userAgent.toLowerCase(),
-        isOpera = (ua.indexOf('opera') > -1),
-        isSafari = (ua.indexOf('safari') > -1),
-        isGecko = (!isOpera && !isSafari && ua.indexOf('gecko') > -1),
-        isIE = (!isOpera && ua.indexOf('msie') > -1);
-
-    // regex cache
-    var patterns = {
-        HYPHEN: /(-[a-z])/i
-    };
-
-
-    var toCamel = function(property) {
-        if ( !patterns.HYPHEN.test(property) ) {
-            return property; // no hyphens
-        }
-
-        if (propertyCache[property]) { // already converted
-            return propertyCache[property];
-        }
-
-        while( patterns.HYPHEN.exec(property) ) {
-            property = property.replace(RegExp.$1,
-                    RegExp.$1.substr(1).toUpperCase());
-        }
-
-        propertyCache[property] = property;
-        return property;
-        //return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
-    };
-
-    // branching at load instead of runtime
-    if (document.defaultView && document.defaultView.getComputedStyle) { // W3C DOM method
-        getStyle = function(el, property) {
-            var value = null;
-
-            var computed = document.defaultView.getComputedStyle(el, '');
-            if (computed) { // test computed before touching for safari
-                value = computed[toCamel(property)];
-            }
-
-            return el.style[property] || value;
-        };
-    } else if (document.documentElement.currentStyle && isIE) { // IE method
-        getStyle = function(el, property) {
-            switch( toCamel(property) ) {
-                case 'opacity' :// IE opacity uses filter
-                    var val = 100;
-                    try { // will error if no DXImageTransform
-                        val = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;
-
-                    } catch(e) {
-                        try { // make sure its in the document
-                            val = el.filters('alpha').opacity;
-                        } catch(e) {
-                        }
-                    }
-                    return val / 100;
-                    break;
-                default:
-                    // test currentStyle before touching
-                    var value = el.currentStyle ? el.currentStyle[property] : null;
-                    return ( el.style[property] || value );
-            }
-        };
-    } else { // default to inline only
-        getStyle = function(el, property) { return el.style[property]; };
-    }
-
-    if (isIE) {
-        setStyle = function(el, property, val) {
-            switch (property) {
-                case 'opacity':
-                    if ( typeof el.style.filter == 'string' ) { // in case not appended
-                        el.style.filter = 'alpha(opacity=' + val * 100 + ')';
-
-                        if (!el.currentStyle || !el.currentStyle.hasLayout) {
-                            el.style.zoom = 1; // when no layout or cant tell
-                        }
-                    }
-                    break;
-                default:
-                el.style[property] = val;
-            }
-        };
-    } else {
-        setStyle = function(el, property, val) {
-            el.style[property] = val;
-        };
-    }
-
-    /**
-     * Provides helper methods for DOM elements.
-     * @namespace YAHOO.util
-     * @class Dom
-     */
-    YAHOO.util.Dom = {
-        /**
-         * Returns an HTMLElement reference.
-         * @method get
-         * @param {String | HTMLElement |Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements.
-         * @return {HTMLElement | Array} A DOM reference to an HTML element or an array of HTMLElements.
-         */
-        get: function(el) {
-            if (!el) { return null; } // nothing to work with
-
-            if (typeof el != 'string' && !(el instanceof Array) ) { // assuming HTMLElement or HTMLCollection, so pass back as is
-                return el;
-            }
-
-            if (typeof el == 'string') { // ID
-                return document.getElementById(el);
-            }
-            else { // array of ID's and/or elements
-                var collection = [];
-                for (var i = 0, len = el.length; i < len; ++i) {
-                    collection[collection.length] = Y.Dom.get(el[i]);
-                }
-
-                return collection;
-            }
-
-            return null; // safety, should never happen
-        },
-
-        /**
-         * Normalizes currentStyle and ComputedStyle.
-         * @method getStyle
-         * @param {String | HTMLElement |Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
-         * @param {String} property The style property whose value is returned.
-         * @return {String | Array} The current value of the style property for the element(s).
-         */
-        getStyle: function(el, property) {
-            property = toCamel(property);
-
-            var f = function(element) {
-                return getStyle(element, property);
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Wrapper for setting style properties of HTMLElements.  Normalizes "opacity" across modern browsers.
-         * @method setStyle
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
-         * @param {String} property The style property to be set.
-         * @param {String} val The value to apply to the given property.
-         */
-        setStyle: function(el, property, val) {
-            property = toCamel(property);
-
-            var f = function(element) {
-                setStyle(element, property, val);
-
-            };
-
-            Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Gets the current position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
-         * @method getXY
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
-         * @return {Array} The XY position of the element(s)
-         */
-        getXY: function(el) {
-            var f = function(el) {
-
-            // has to be part of document to have pageXY
-                if (el.parentNode === null || el.offsetParent === null ||
-                        this.getStyle(el, 'display') == 'none') {
-                    return false;
-                }
-
-                var parentNode = null;
-                var pos = [];
-                var box;
-
-                if (el.getBoundingClientRect) { // IE
-                    box = el.getBoundingClientRect();
-                    var doc = document;
-                    if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll
-                        doc = parent.document;
-
-                        if ( !this.isAncestor(doc.documentElement, el) ) {
-                            return false;
-                        }
-
-                    }
-
-                    var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
-                    var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
-
-                    return [box.left + scrollLeft, box.top + scrollTop];
-                }
-                else { // safari, opera, & gecko
-                    pos = [el.offsetLeft, el.offsetTop];
-                    parentNode = el.offsetParent;
-                    if (parentNode != el) {
-                        while (parentNode) {
-                            pos[0] += parentNode.offsetLeft;
-                            pos[1] += parentNode.offsetTop;
-                            parentNode = parentNode.offsetParent;
-                        }
-                    }
-                    if (isSafari && this.getStyle(el, 'position') == 'absolute' ) { // safari doubles in some cases
-                        pos[0] -= document.body.offsetLeft;
-                        pos[1] -= document.body.offsetTop;
-                    }
-                }
-
-                if (el.parentNode) { parentNode = el.parentNode; }
-                else { parentNode = null; }
-
-                while (parentNode && parentNode.tagName.toUpperCase() != 'BODY' && parentNode.tagName.toUpperCase() != 'HTML')
-                { // account for any scrolled ancestors
-                    if (Y.Dom.getStyle(parentNode, 'display') != 'inline') { // work around opera inline scrollLeft/Top bug
-                        pos[0] -= parentNode.scrollLeft;
-                        pos[1] -= parentNode.scrollTop;
-                    }
-
-                    if (parentNode.parentNode) {
-                        parentNode = parentNode.parentNode;
-                    } else { parentNode = null; }
-                }
-
-
-                return pos;
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Gets the current X position of an element based on page coordinates.  The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
-         * @method getX
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
-         * @return {String | Array} The X position of the element(s)
-         */
-        getX: function(el) {
-            var f = function(el) {
-                return Y.Dom.getXY(el)[0];
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Gets the current Y position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
-         * @method getY
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
-         * @return {String | Array} The Y position of the element(s)
-         */
-        getY: function(el) {
-            var f = function(el) {
-                return Y.Dom.getXY(el)[1];
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Set the position of an html element in page coordinates, regardless of how the element is positioned.
-         * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
-         * @method setXY
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
-         * @param {Array} pos Contains X & Y values for new position (coordinates are page-based)
-         * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
-         */
-        setXY: function(el, pos, noRetry) {
-            var f = function(el) {
-                var style_pos = this.getStyle(el, 'position');
-                if (style_pos == 'static') { // default to relative
-                    this.setStyle(el, 'position', 'relative');
-                    style_pos = 'relative';
-                }
-
-                var pageXY = this.getXY(el);
-                if (pageXY === false) { // has to be part of doc to have pageXY
-                    return false;
-                }
-
-                var delta = [ // assuming pixels; if not we will have to retry
-                    parseInt( this.getStyle(el, 'left'), 10 ),
-                    parseInt( this.getStyle(el, 'top'), 10 )
-                ];
-
-                if ( isNaN(delta[0]) ) {// in case of 'auto'
-                    delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft;
-                }
-                if ( isNaN(delta[1]) ) { // in case of 'auto'
-                    delta[1] = (style_pos == 'relative') ? 0 : el.offsetTop;
-                }
-
-                if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; }
-                if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; }
-
-                if (!noRetry) {
-                    var newXY = this.getXY(el);
-
-                    // if retry is true, try one more time if we miss
-                   if ( (pos[0] !== null && newXY[0] != pos[0]) ||
-                        (pos[1] !== null && newXY[1] != pos[1]) ) {
-                       this.setXY(el, pos, true);
-                   }
-                }
-
-            };
-
-            Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
-         * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
-         * @method setX
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
-         * @param {Int} x The value to use as the X coordinate for the element(s).
-         */
-        setX: function(el, x) {
-            Y.Dom.setXY(el, [x, null]);
-        },
-
-        /**
-         * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
-         * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
-         * @method setY
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
-         * @param {Int} x To use as the Y coordinate for the element(s).
-         */
-        setY: function(el, y) {
-            Y.Dom.setXY(el, [null, y]);
-        },
-
-        /**
-         * Returns the region position of the given element.
-         * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
-         * @method getRegion
-         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
-         * @return {Region | Array} A Region or array of Region instances containing "top, left, bottom, right" member data.
-         */
-        getRegion: function(el) {
-            var f = function(el) {
-                var region = new Y.Region.getRegion(el);
-                return region;
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Returns the width of the client (viewport).
-         * @method getClientWidth
-         * @deprecated Now using getViewportWidth.  This interface left intact for back compat.
-         * @return {Int} The width of the viewable area of the page.
-         */
-        getClientWidth: function() {
-            return Y.Dom.getViewportWidth();
-        },
-
-        /**
-         * Returns the height of the client (viewport).
-         * @method getClientHeight
-         * @deprecated Now using getViewportHeight.  This interface left intact for back compat.
-         * @return {Int} The height of the viewable area of the page.
-         */
-        getClientHeight: function() {
-            return Y.Dom.getViewportHeight();
-        },
-
-        /**
-         * Returns a array of HTMLElements with the given class.
-         * For optimized performance, include a tag and/or root node when possible.
-         * @method getElementsByClassName
-         * @param {String} className The class name to match against
-         * @param {String} tag (optional) The tag name of the elements being collected
-         * @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point
-         * @return {Array} An array of elements that have the given class name
-         */
-        getElementsByClassName: function(className, tag, root) {
-            var method = function(el) { return Y.Dom.hasClass(el, className); };
-            return Y.Dom.getElementsBy(method, tag, root);
-        },
-
-        /**
-         * Determines whether an HTMLElement has the given className.
-         * @method hasClass
-         * @param {String | HTMLElement | Array} el The element or collection to test
-         * @param {String} className the class name to search for
-         * @return {Boolean | Array} A boolean value or array of boolean values
-         */
-        hasClass: function(el, className) {
-            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
-
-            var f = function(el) {
-                return re.test(el['className']);
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Adds a class name to a given element or collection of elements.
-         * @method addClass
-         * @param {String | HTMLElement | Array} el The element or collection to add the class to
-         * @param {String} className the class name to add to the class attribute
-         */
-        addClass: function(el, className) {
-            var f = function(el) {
-                if (this.hasClass(el, className)) { return; } // already present
-
-
-                el['className'] = [el['className'], className].join(' ');
-            };
-
-            Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Removes a class name from a given element or collection of elements.
-         * @method removeClass
-         * @param {String | HTMLElement | Array} el The element or collection to remove the class from
-         * @param {String} className the class name to remove from the class attribute
-         */
-        removeClass: function(el, className) {
-            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');
-
-            var f = function(el) {
-                if (!this.hasClass(el, className)) { return; } // not present
-
-
-                var c = el['className'];
-                el['className'] = c.replace(re, ' ');
-                if ( this.hasClass(el, className) ) { // in case of multiple adjacent
-                    this.removeClass(el, className);
-                }
-
-            };
-
-            Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Replace a class with another class for a given element or collection of elements.
-         * If no oldClassName is present, the newClassName is simply added.
-         * @method replaceClass
-         * @param {String | HTMLElement | Array} el The element or collection to remove the class from
-         * @param {String} oldClassName the class name to be replaced
-         * @param {String} newClassName the class name that will be replacing the old class name
-         */
-        replaceClass: function(el, oldClassName, newClassName) {
-            if (oldClassName === newClassName) { // avoid infinite loop
-                return false;
-            }
-
-            var re = new RegExp('(?:^|\\s+)' + oldClassName + '(?:\\s+|$)', 'g');
-
-            var f = function(el) {
-
-                if ( !this.hasClass(el, oldClassName) ) {
-                    this.addClass(el, newClassName); // just add it if nothing to replace
-                    return; // note return
-                }
-
-                el['className'] = el['className'].replace(re, ' ' + newClassName + ' ');
-
-                if ( this.hasClass(el, oldClassName) ) { // in case of multiple adjacent
-                    this.replaceClass(el, oldClassName, newClassName);
-                }
-            };
-
-            Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Generates a unique ID
-         * @method generateId
-         * @param {String | HTMLElement | Array} el (optional) An optional element array of elements to add an ID to (no ID is added if one is already present).
-         * @param {String} prefix (optional) an optional prefix to use (defaults to "yui-gen").
-         * @return {String | Array} The generated ID, or array of generated IDs (or original ID if already present on an element)
-         */
-        generateId: function(el, prefix) {
-            prefix = prefix || 'yui-gen';
-            el = el || {};
-
-            var f = function(el) {
-                if (el) {
-                    el = Y.Dom.get(el);
-                } else {
-                    el = {}; // just generating ID in this case
-                }
-
-                if (!el.id) {
-                    el.id = prefix + id_counter++;
-                } // dont override existing
-
-
-                return el.id;
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Determines whether an HTMLElement is an ancestor of another HTML element in the DOM hierarchy.
-         * @method isAncestor
-         * @param {String | HTMLElement} haystack The possible ancestor
-         * @param {String | HTMLElement} needle The possible descendent
-         * @return {Boolean} Whether or not the haystack is an ancestor of needle
-         */
-        isAncestor: function(haystack, needle) {
-            haystack = Y.Dom.get(haystack);
-            if (!haystack || !needle) { return false; }
-
-            var f = function(needle) {
-                if (haystack.contains && !isSafari) { // safari "contains" is broken
-                    return haystack.contains(needle);
-                }
-                else if ( haystack.compareDocumentPosition ) {
-                    return !!(haystack.compareDocumentPosition(needle) & 16);
-                }
-                else { // loop up and test each parent
-                    var parent = needle.parentNode;
-
-                    while (parent) {
-                        if (parent == haystack) {
-                            return true;
-                        }
-                        else if (!parent.tagName || parent.tagName.toUpperCase() == 'HTML') {
-                            return false;
-                        }
-
-                        parent = parent.parentNode;
-                    }
-                    return false;
-                }
-            };
-
-            return Y.Dom.batch(needle, f, Y.Dom, true);
-        },
-
-        /**
-         * Determines whether an HTMLElement is present in the current document.
-         * @method inDocument
-         * @param {String | HTMLElement} el The element to search for
-         * @return {Boolean} Whether or not the element is present in the current document
-         */
-        inDocument: function(el) {
-            var f = function(el) {
-                return this.isAncestor(document.documentElement, el);
-            };
-
-            return Y.Dom.batch(el, f, Y.Dom, true);
-        },
-
-        /**
-         * Returns a array of HTMLElements that pass the test applied by supplied boolean method.
-         * For optimized performance, include a tag and/or root node when possible.
-         * @method getElementsBy
-         * @param {Function} method - A boolean method for testing elements which receives the element as its only argument.
-
-         * @param {String} tag (optional) The tag name of the elements being collected
-         * @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point
-         */
-        getElementsBy: function(method, tag, root) {
-            tag = tag || '*';
-
-            var nodes = [];
-
-            if (root) {
-                root = Y.Dom.get(root);
-                if (!root) { // if no root node, then no children
-                    return nodes;
-                }
-            } else {
-                root = document;
-            }
-
-            var elements = root.getElementsByTagName(tag);
-
-            if ( !elements.length && (tag == '*' && root.all) ) {
-                elements = root.all; // IE < 6
-            }
-
-            for (var i = 0, len = elements.length; i < len; ++i) {
-                if ( method(elements[i]) ) { nodes[nodes.length] = elements[i]; }
-            }
-
-
-            return nodes;
-        },
-
-        /**
-         * Returns an array of elements that have had the supplied method applied.
-         * The method is called with the element(s) as the first arg, and the optional param as the second ( method(el, o) ).
-         * @method batch
-         * @param {String | HTMLElement | Array} el (optional) An element or array of elements to apply the method to
-         * @param {Function} method The method to apply to the element(s)
-         * @param {Any} o (optional) An optional arg that is passed to the supplied method
-         * @param {Boolean} override (optional) Whether or not to override the scope of "method" with "o"
-         * @return {HTMLElement | Array} The element(s) with the method applied
-         */
-        batch: function(el, method, o, override) {
-            var id = el;
-            el = Y.Dom.get(el);
-
-            var scope = (override) ? o : window;
-
-            if (!el || el.tagName || !el.length) { // is null or not a collection (tagName for SELECT and others that can be both an element and a collection)
-                if (!el) {
-                    return false;
-                }
-                return method.call(scope, el, o);
-            }
-
-            var collection = [];
-
-            for (var i = 0, len = el.length; i < len; ++i) {
-                if (!el[i]) {
-                    id = el[i];
-                }
-                collection[collection.length] = method.call(scope, el[i], o);
-            }
-
-            return collection;
-        },
-
-        /**
-         * Returns the height of the document.
-         * @method getDocumentHeight
-         * @return {Int} The height of the actual document (which includes the body and its margin).
-         */
-        getDocumentHeight: function() {
-            var scrollHeight = (document.compatMode != 'CSS1Compat') ? document.body.scrollHeight : document.documentElement.scrollHeight;
-
-            var h = Math.max(scrollHeight, Y.Dom.getViewportHeight());
-            return h;
-        },
-
-        /**
-         * Returns the width of the document.
-         * @method getDocumentWidth
-         * @return {Int} The width of the actual document (which includes the body and its margin).
-         */
-        getDocumentWidth: function() {
-            var scrollWidth = (document.compatMode != 'CSS1Compat') ? document.body.scrollWidth : document.documentElement.scrollWidth;
-            var w = Math.max(scrollWidth, Y.Dom.getViewportWidth());
-            return w;
-        },
-
-        /**
-         * Returns the current height of the viewport.
-         * @method getViewportHeight
-         * @return {Int} The height of the viewable area of the page (excludes scrollbars).
-         */
-        getViewportHeight: function() {
-            var height = self.innerHeight; // Safari, Opera
-            var mode = document.compatMode;
-
-            if ( (mode || isIE) && !isOpera ) { // IE, Gecko
-                height = (mode == 'CSS1Compat') ?
-                        document.documentElement.clientHeight : // Standards
-                        document.body.clientHeight; // Quirks
-            }
-
-            return height;
-        },
-
-        /**
-         * Returns the current width of the viewport.
-         * @method getViewportWidth
-         * @return {Int} The width of the viewable area of the page (excludes scrollbars).
-         */
-
-        getViewportWidth: function() {
-            var width = self.innerWidth;  // Safari
-            var mode = document.compatMode;
-
-            if (mode || isIE) { // IE, Gecko, Opera
-                width = (mode == 'CSS1Compat') ?
-                        document.documentElement.clientWidth : // Standards
-                        document.body.clientWidth; // Quirks
-            }
-            return width;
-        }
-    };
-})();
-/**
- * A region is a representation of an object on a grid.  It is defined
- * by the top, right, bottom, left extents, so is rectangular by default.  If
- * other shapes are required, this class could be extended to support it.
- * @namespace YAHOO.util
- * @class Region
- * @param {Int} t the top extent
- * @param {Int} r the right extent
- * @param {Int} b the bottom extent
- * @param {Int} l the left extent
- * @constructor
- */
-YAHOO.util.Region = function(t, r, b, l) {
-
-    /**
-     * The region's top extent
-     * @property top
-     * @type Int
-     */
-    this.top = t;
-
-    /**
-     * The region's top extent as index, for symmetry with set/getXY
-     * @property 1
-     * @type Int
-     */
-    this[1] = t;
-
-    /**
-     * The region's right extent
-     * @property right
-     * @type int
-     */
-    this.right = r;
-
-    /**
-     * The region's bottom extent
-     * @property bottom
-     * @type Int
-     */
-    this.bottom = b;
-
-    /**
-     * The region's left extent
-     * @property left
-     * @type Int
-     */
-    this.left = l;
-
-    /**
-     * The region's left extent as index, for symmetry with set/getXY
-     * @property 0
-     * @type Int
-     */
-    this[0] = l;
-};
-
-/**
- * Returns true if this region contains the region passed in
- * @method contains
- * @param  {Region}  region The region to evaluate
- * @return {Boolean}        True if the region is contained with this region,
- *                          else false
- */
-YAHOO.util.Region.prototype.contains = function(region) {
-    return ( region.left   >= this.left   &&
-             region.right  <= this.right  &&
-             region.top    >= this.top    &&
-             region.bottom <= this.bottom    );
-
-};
-
-/**
- * Returns the area of the region
- * @method getArea
- * @return {Int} the region's area
- */
-YAHOO.util.Region.prototype.getArea = function() {
-    return ( (this.bottom - this.top) * (this.right - this.left) );
-};
-
-/**
- * Returns the region where the passed in region overlaps with this one
- * @method intersect
- * @param  {Region} region The region that intersects
- * @return {Region}        The overlap region, or null if there is no overlap
- */
-YAHOO.util.Region.prototype.intersect = function(region) {
-    var t = Math.max( this.top,    region.top    );
-    var r = Math.min( this.right,  region.right  );
-    var b = Math.min( this.bottom, region.bottom );
-    var l = Math.max( this.left,   region.left   );
-
-    if (b >= t && r >= l) {
-        return new YAHOO.util.Region(t, r, b, l);
-    } else {
-        return null;
-    }
-};
-
-/**
- * Returns the region representing the smallest region that can contain both
- * the passed in region and this region.
- * @method union
- * @param  {Region} region The region that to create the union with
- * @return {Region}        The union region
- */
-YAHOO.util.Region.prototype.union = function(region) {
-    var t = Math.min( this.top,    region.top    );
-    var r = Math.max( this.right,  region.right  );
-    var b = Math.max( this.bottom, region.bottom );
-    var l = Math.min( this.left,   region.left   );
-
-    return new YAHOO.util.Region(t, r, b, l);
-};
-
-/**
- * toString
- * @method toString
- * @return string the region properties
- */
-YAHOO.util.Region.prototype.toString = function() {
-    return ( "Region {"    +
-             "top: "       + this.top    +
-             ", right: "   + this.right  +
-             ", bottom: "  + this.bottom +
-             ", left: "    + this.left   +
-             "}" );
-};
-
-/**
- * Returns a region that is occupied by the DOM element
- * @method getRegion
- * @param  {HTMLElement} el The element
- * @return {Region}         The region that the element occupies
- * @static
- */
-YAHOO.util.Region.getRegion = function(el) {
-    var p = YAHOO.util.Dom.getXY(el);
-
-    var t = p[1];
-    var r = p[0] + el.offsetWidth;
-    var b = p[1] + el.offsetHeight;
-    var l = p[0];
-
-    return new YAHOO.util.Region(t, r, b, l);
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * A point is a region that is special in that it represents a single point on
- * the grid.
- * @namespace YAHOO.util
- * @class Point
- * @param {Int} x The X position of the point
- * @param {Int} y The Y position of the point
- * @constructor
- * @extends YAHOO.util.Region
- */
-YAHOO.util.Point = function(x, y) {
-   if (x instanceof Array) { // accept output from Dom.getXY
-      y = x[1];
-      x = x[0];
-   }
-
-    /**
-     * The X position of the point, which is also the right, left and index zero (for Dom.getXY symmetry)
-     * @property x
-     * @type Int
-     */
-
-    this.x = this.right = this.left = this[0] = x;
-
-    /**
-     * The Y position of the point, which is also the top, bottom and index one (for Dom.getXY symmetry)
-     * @property y
-     * @type Int
-     */
-    this.y = this.top = this.bottom = this[1] = y;
-};
-
-YAHOO.util.Point.prototype = new YAHOO.util.Region();
-
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/*
+Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+*/
+
+/**
+ * The dom module provides helper methods for manipulating Dom elements.
+ * @module dom
+ *
+ */
+
+(function() {
+    var Y = YAHOO.util,     // internal shorthand
+        getStyle,           // for load time browser branching
+        setStyle,           // ditto
+        id_counter = 0,     // for use with generateId
+        propertyCache = {}; // for faster hyphen converts
+    
+    // brower detection
+    var ua = navigator.userAgent.toLowerCase(),
+        isOpera = (ua.indexOf('opera') > -1),
+        isSafari = (ua.indexOf('safari') > -1),
+        isGecko = (!isOpera && !isSafari && ua.indexOf('gecko') > -1),
+        isIE = (!isOpera && ua.indexOf('msie') > -1); 
+    
+    // regex cache
+    var patterns = {
+        HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
+        ROOT_TAG: /body|html/i // body for quirks mode, html for standards
+    };
+
+    var toCamel = function(property) {
+        if ( !patterns.HYPHEN.test(property) ) {
+            return property; // no hyphens
+        }
+        
+        if (propertyCache[property]) { // already converted
+            return propertyCache[property];
+        }
+       
+        var converted = property;
+ 
+        while( patterns.HYPHEN.exec(converted) ) {
+            converted = converted.replace(RegExp.$1,
+                    RegExp.$1.substr(1).toUpperCase());
+        }
+        
+        propertyCache[property] = converted;
+        return converted;
+        //return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
+    };
+    
+    // branching at load instead of runtime
+    if (document.defaultView && document.defaultView.getComputedStyle) { // W3C DOM method
+        getStyle = function(el, property) {
+            var value = null;
+            
+            if (property == 'float') { // fix reserved word
+                property = 'cssFloat';
+            }
+
+            var computed = document.defaultView.getComputedStyle(el, '');
+            if (computed) { // test computed before touching for safari
+                value = computed[toCamel(property)];
+            }
+            
+            return el.style[property] || value;
+        };
+    } else if (document.documentElement.currentStyle && isIE) { // IE method
+        getStyle = function(el, property) {                         
+            switch( toCamel(property) ) {
+                case 'opacity' :// IE opacity uses filter
+                    var val = 100;
+                    try { // will error if no DXImageTransform
+                        val = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;
+
+                    } catch(e) {
+                        try { // make sure its in the document
+                            val = el.filters('alpha').opacity;
+                        } catch(e) {
+                        }
+                    }
+                    return val / 100;
+                    break;
+                case 'float': // fix reserved word
+                    property = 'styleFloat'; // fall through
+                default: 
+                    // test currentStyle before touching
+                    var value = el.currentStyle ? el.currentStyle[property] : null;
+                    return ( el.style[property] || value );
+            }
+        };
+    } else { // default to inline only
+        getStyle = function(el, property) { return el.style[property]; };
+    }
+    
+    if (isIE) {
+        setStyle = function(el, property, val) {
+            switch (property) {
+                case 'opacity':
+                    if ( YAHOO.lang.isString(el.style.filter) ) { // in case not appended
+                        el.style.filter = 'alpha(opacity=' + val * 100 + ')';
+                        
+                        if (!el.currentStyle || !el.currentStyle.hasLayout) {
+                            el.style.zoom = 1; // when no layout or cant tell
+                        }
+                    }
+                    break;
+                case 'float':
+                    property = 'styleFloat';
+                default:
+                el.style[property] = val;
+            }
+        };
+    } else {
+        setStyle = function(el, property, val) {
+            if (property == 'float') {
+                property = 'cssFloat';
+            }
+            el.style[property] = val;
+        };
+    }
+    
+    /**
+     * Provides helper methods for DOM elements.
+     * @namespace YAHOO.util
+     * @class Dom
+     */
+    YAHOO.util.Dom = {
+        /**
+         * Returns an HTMLElement reference.
+         * @method get
+         * @param {String | HTMLElement |Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements.
+         * @return {HTMLElement | Array} A DOM reference to an HTML element or an array of HTMLElements.
+         */
+        get: function(el) {
+            if ( YAHOO.lang.isString(el) ) { // ID 
+                return document.getElementById(el);
+            }
+            
+            if ( YAHOO.lang.isArray(el) ) { // Array of IDs and/or HTMLElements
+                var c = [];
+                for (var i = 0, len = el.length; i < len; ++i) {
+                    c[c.length] = Y.Dom.get(el[i]);
+                }
+                
+                return c;
+            }
+
+            if (el) { // assuming HTMLElement or HTMLCollection, just pass back 
+                return el;
+            }
+
+            return null; // el is likely null or undefined 
+        },
+    
+        /**
+         * Normalizes currentStyle and ComputedStyle.
+         * @method getStyle
+         * @param {String | HTMLElement |Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
+         * @param {String} property The style property whose value is returned.
+         * @return {String | Array} The current value of the style property for the element(s).
+         */
+        getStyle: function(el, property) {
+            property = toCamel(property);
+            
+            var f = function(element) {
+                return getStyle(element, property);
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+    
+        /**
+         * Wrapper for setting style properties of HTMLElements.  Normalizes "opacity" across modern browsers.
+         * @method setStyle
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
+         * @param {String} property The style property to be set.
+         * @param {String} val The value to apply to the given property.
+         */
+        setStyle: function(el, property, val) {
+            property = toCamel(property);
+            
+            var f = function(element) {
+                setStyle(element, property, val);
+                
+            };
+            
+            Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Gets the current position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
+         * @method getXY
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
+         * @return {Array} The XY position of the element(s)
+         */
+        getXY: function(el) {
+            var f = function(el) {
+    
+            // has to be part of document to have pageXY
+                if ( (el.parentNode === null || el.offsetParent === null ||
+                        this.getStyle(el, 'display') == 'none') && el != document.body) {
+                    return false;
+                }
+                
+                var parentNode = null;
+                var pos = [];
+                var box;
+                
+                if (el.getBoundingClientRect) { // IE
+                    box = el.getBoundingClientRect();
+                    var doc = document;
+                    if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll
+                        doc = parent.document;
+
+                        if ( !this.isAncestor(doc.documentElement, el) ) {
+                            return false;                      
+                        }
+
+                    }
+
+                    var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
+                    var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
+                    
+                    return [box.left + scrollLeft, box.top + scrollTop];
+                }
+                else { // safari, opera, & gecko
+                    pos = [el.offsetLeft, el.offsetTop];
+                    parentNode = el.offsetParent;
+
+                    // safari: if el is abs or any parent is abs, subtract body offsets
+                    var hasAbs = this.getStyle(el, 'position') == 'absolute';
+
+                    if (parentNode != el) {
+                        while (parentNode) {
+                            pos[0] += parentNode.offsetLeft;
+                            pos[1] += parentNode.offsetTop;
+                            if (isSafari && !hasAbs && 
+                                    this.getStyle(parentNode,'position') == 'absolute' ) {
+                                hasAbs = true; // we need to offset if any parent is absolutely positioned
+                            }
+                            parentNode = parentNode.offsetParent;
+                        }
+                    }
+
+                    if (isSafari && hasAbs) { //safari doubles in this case
+                        pos[0] -= document.body.offsetLeft;
+                        pos[1] -= document.body.offsetTop;
+                    } 
+                }
+                
+                parentNode = el.parentNode;
+
+                // account for any scrolled ancestors
+                while ( parentNode.tagName && !patterns.ROOT_TAG.test(parentNode.tagName) ) 
+                {
+                   // work around opera inline scrollLeft/Top bug
+                   if (isOpera && Y.Dom.getStyle(parentNode, 'display') != 'inline') { 
+                        pos[0] -= parentNode.scrollLeft;
+                        pos[1] -= parentNode.scrollTop;
+                    }
+                    
+                    parentNode = parentNode.parentNode; 
+                }
+        
+                
+                return pos;
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Gets the current X position of an element based on page coordinates.  The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
+         * @method getX
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
+         * @return {String | Array} The X position of the element(s)
+         */
+        getX: function(el) {
+            var f = function(el) {
+                return Y.Dom.getXY(el)[0];
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Gets the current Y position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
+         * @method getY
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
+         * @return {String | Array} The Y position of the element(s)
+         */
+        getY: function(el) {
+            var f = function(el) {
+                return Y.Dom.getXY(el)[1];
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Set the position of an html element in page coordinates, regardless of how the element is positioned.
+         * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
+         * @method setXY
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
+         * @param {Array} pos Contains X & Y values for new position (coordinates are page-based)
+         * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
+         */
+        setXY: function(el, pos, noRetry) {
+            var f = function(el) {
+                var style_pos = this.getStyle(el, 'position');
+                if (style_pos == 'static') { // default to relative
+                    this.setStyle(el, 'position', 'relative');
+                    style_pos = 'relative';
+                }
+
+                var pageXY = this.getXY(el);
+                if (pageXY === false) { // has to be part of doc to have pageXY
+                    return false; 
+                }
+                
+                var delta = [ // assuming pixels; if not we will have to retry
+                    parseInt( this.getStyle(el, 'left'), 10 ),
+                    parseInt( this.getStyle(el, 'top'), 10 )
+                ];
+            
+                if ( isNaN(delta[0]) ) {// in case of 'auto'
+                    delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft;
+                } 
+                if ( isNaN(delta[1]) ) { // in case of 'auto'
+                    delta[1] = (style_pos == 'relative') ? 0 : el.offsetTop;
+                } 
+        
+                if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; }
+                if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; }
+              
+                if (!noRetry) {
+                    var newXY = this.getXY(el);
+
+                    // if retry is true, try one more time if we miss 
+                   if ( (pos[0] !== null && newXY[0] != pos[0]) || 
+                        (pos[1] !== null && newXY[1] != pos[1]) ) {
+                       this.setXY(el, pos, true);
+                   }
+                }        
+        
+            };
+            
+            Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
+         * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
+         * @method setX
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
+         * @param {Int} x The value to use as the X coordinate for the element(s).
+         */
+        setX: function(el, x) {
+            Y.Dom.setXY(el, [x, null]);
+        },
+        
+        /**
+         * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
+         * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
+         * @method setY
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
+         * @param {Int} x To use as the Y coordinate for the element(s).
+         */
+        setY: function(el, y) {
+            Y.Dom.setXY(el, [null, y]);
+        },
+        
+        /**
+         * Returns the region position of the given element.
+         * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
+         * @method getRegion
+         * @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
+         * @return {Region | Array} A Region or array of Region instances containing "top, left, bottom, right" member data.
+         */
+        getRegion: function(el) {
+            var f = function(el) {
+                var region = new Y.Region.getRegion(el);
+                return region;
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Returns the width of the client (viewport).
+         * @method getClientWidth
+         * @deprecated Now using getViewportWidth.  This interface left intact for back compat.
+         * @return {Int} The width of the viewable area of the page.
+         */
+        getClientWidth: function() {
+            return Y.Dom.getViewportWidth();
+        },
+        
+        /**
+         * Returns the height of the client (viewport).
+         * @method getClientHeight
+         * @deprecated Now using getViewportHeight.  This interface left intact for back compat.
+         * @return {Int} The height of the viewable area of the page.
+         */
+        getClientHeight: function() {
+            return Y.Dom.getViewportHeight();
+        },
+
+        /**
+         * Returns a array of HTMLElements with the given class.
+         * For optimized performance, include a tag and/or root node when possible.
+         * @method getElementsByClassName
+         * @param {String} className The class name to match against
+         * @param {String} tag (optional) The tag name of the elements being collected
+         * @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point 
+         * @return {Array} An array of elements that have the given class name
+         */
+        getElementsByClassName: function(className, tag, root) {
+            var method = function(el) { return Y.Dom.hasClass(el, className); };
+            return Y.Dom.getElementsBy(method, tag, root);
+        },
+
+        /**
+         * Determines whether an HTMLElement has the given className.
+         * @method hasClass
+         * @param {String | HTMLElement | Array} el The element or collection to test
+         * @param {String} className the class name to search for
+         * @return {Boolean | Array} A boolean value or array of boolean values
+         */
+        hasClass: function(el, className) {
+            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
+            
+            var f = function(el) {
+                return re.test(el.className);
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+    
+        /**
+         * Adds a class name to a given element or collection of elements.
+         * @method addClass         
+         * @param {String | HTMLElement | Array} el The element or collection to add the class to
+         * @param {String} className the class name to add to the class attribute
+         */
+        addClass: function(el, className) {
+            var f = function(el) {
+                if (this.hasClass(el, className)) { return; } // already present
+                
+                
+                el.className = [el.className, className].join(' ');
+            };
+            
+            Y.Dom.batch(el, f, Y.Dom, true);
+        },
+    
+        /**
+         * Removes a class name from a given element or collection of elements.
+         * @method removeClass         
+         * @param {String | HTMLElement | Array} el The element or collection to remove the class from
+         * @param {String} className the class name to remove from the class attribute
+         */
+        removeClass: function(el, className) {
+            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');
+
+            var f = function(el) {
+                if (!this.hasClass(el, className)) {
+                    return; // not present
+                }                 
+
+                
+                var c = el.className;
+                el.className = c.replace(re, ' ');
+                if ( this.hasClass(el, className) ) { // in case of multiple adjacent
+                    this.removeClass(el, className);
+                }
+                
+            };
+            
+            Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Replace a class with another class for a given element or collection of elements.
+         * If no oldClassName is present, the newClassName is simply added.
+         * @method replaceClass  
+         * @param {String | HTMLElement | Array} el The element or collection to remove the class from
+         * @param {String} oldClassName the class name to be replaced
+         * @param {String} newClassName the class name that will be replacing the old class name
+         */
+        replaceClass: function(el, oldClassName, newClassName) {
+            if (oldClassName === newClassName) { // avoid infinite loop
+                return false;
+            }
+            
+            var re = new RegExp('(?:^|\\s+)' + oldClassName + '(?:\\s+|$)', 'g');
+
+            var f = function(el) {
+            
+                if ( !this.hasClass(el, oldClassName) ) {
+                    this.addClass(el, newClassName); // just add it if nothing to replace
+                    return; // note return
+                }
+            
+                el.className = el.className.replace(re, ' ' + newClassName + ' ');
+
+                if ( this.hasClass(el, oldClassName) ) { // in case of multiple adjacent
+                    this.replaceClass(el, oldClassName, newClassName);
+                }
+            };
+            
+            Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Generates a unique ID
+         * @method generateId  
+         * @param {String | HTMLElement | Array} el (optional) An optional element array of elements to add an ID to (no ID is added if one is already present).
+         * @param {String} prefix (optional) an optional prefix to use (defaults to "yui-gen").
+         * @return {String | Array} The generated ID, or array of generated IDs (or original ID if already present on an element)
+         */
+        generateId: function(el, prefix) {
+            prefix = prefix || 'yui-gen';
+            el = el || {};
+            
+            var f = function(el) {
+                if (el) {
+                    el = Y.Dom.get(el);
+                } else {
+                    el = {}; // just generating ID in this case
+                }
+                
+                if (!el.id) {
+                    el.id = prefix + id_counter++; 
+                } // dont override existing
+                
+                
+                return el.id;
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Determines whether an HTMLElement is an ancestor of another HTML element in the DOM hierarchy.
+         * @method isAncestor
+         * @param {String | HTMLElement} haystack The possible ancestor
+         * @param {String | HTMLElement} needle The possible descendent
+         * @return {Boolean} Whether or not the haystack is an ancestor of needle
+         */
+        isAncestor: function(haystack, needle) {
+            haystack = Y.Dom.get(haystack);
+            if (!haystack || !needle) { return false; }
+            
+            var f = function(needle) {
+                if (haystack.contains && !isSafari) { // safari "contains" is broken
+                    return haystack.contains(needle);
+                }
+                else if ( haystack.compareDocumentPosition ) {
+                    return !!(haystack.compareDocumentPosition(needle) & 16);
+                }
+                else { // loop up and test each parent
+                    var parent = needle.parentNode;
+                    
+                    while (parent) {
+                        if (parent == haystack) {
+                            return true;
+                        }
+                        else if (!parent.tagName || parent.tagName.toUpperCase() == 'HTML') {
+                            return false;
+                        }
+                        
+                        parent = parent.parentNode;
+                    }
+                    return false;
+                }     
+            };
+            
+            return Y.Dom.batch(needle, f, Y.Dom, true);      
+        },
+        
+        /**
+         * Determines whether an HTMLElement is present in the current document.
+         * @method inDocument         
+         * @param {String | HTMLElement} el The element to search for
+         * @return {Boolean} Whether or not the element is present in the current document
+         */
+        inDocument: function(el) {
+            var f = function(el) {
+                return this.isAncestor(document.documentElement, el);
+            };
+            
+            return Y.Dom.batch(el, f, Y.Dom, true);
+        },
+        
+        /**
+         * Returns a array of HTMLElements that pass the test applied by supplied boolean method.
+         * For optimized performance, include a tag and/or root node when possible.
+         * @method getElementsBy
+         * @param {Function} method - A boolean method for testing elements which receives the element as its only argument.
+
+         * @param {String} tag (optional) The tag name of the elements being collected
+         * @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point 
+         * @return {Array} Array of HTMLElements
+         */
+        getElementsBy: function(method, tag, root) {
+            tag = tag || '*';
+            
+            var nodes = [];
+            
+            if (root) {
+                root = Y.Dom.get(root);
+                if (!root) { // if no root node, then no children
+                    return nodes;
+                }
+            } else {
+                root = document;
+            }
+            
+            var elements = root.getElementsByTagName(tag);
+            
+            if ( !elements.length && (tag == '*' && root.all) ) {
+                elements = root.all; // IE < 6
+            }
+            
+            for (var i = 0, len = elements.length; i < len; ++i) {
+                if ( method(elements[i]) ) { nodes[nodes.length] = elements[i]; }
+            }
+
+            
+            return nodes;
+        },
+        
+        /**
+         * Returns an array of elements that have had the supplied method applied.
+         * The method is called with the element(s) as the first arg, and the optional param as the second ( method(el, o) ).
+         * @method batch
+         * @param {String | HTMLElement | Array} el (optional) An element or array of elements to apply the method to
+         * @param {Function} method The method to apply to the element(s)
+         * @param {Any} o (optional) An optional arg that is passed to the supplied method
+         * @param {Boolean} override (optional) Whether or not to override the scope of "method" with "o"
+         * @return {HTMLElement | Array} The element(s) with the method applied
+         */
+        batch: function(el, method, o, override) {
+            var id = el;
+            el = Y.Dom.get(el);
+            
+            var scope = (override) ? o : window;
+            
+            if (!el || el.tagName || !el.length) { // is null or not a collection (tagName for SELECT and others that can be both an element and a collection)
+                if (!el) {
+                    return false;
+                }
+                return method.call(scope, el, o);
+            } 
+            
+            var collection = [];
+            
+            for (var i = 0, len = el.length; i < len; ++i) {
+                if (!el[i]) {
+                    id = el[i];
+                }
+                collection[collection.length] = method.call(scope, el[i], o);
+            }
+            
+            return collection;
+        },
+        
+        /**
+         * Returns the height of the document.
+         * @method getDocumentHeight
+         * @return {Int} The height of the actual document (which includes the body and its margin).
+         */
+        getDocumentHeight: function() {
+            var scrollHeight = (document.compatMode != 'CSS1Compat') ? document.body.scrollHeight : document.documentElement.scrollHeight;
+
+            var h = Math.max(scrollHeight, Y.Dom.getViewportHeight());
+            return h;
+        },
+        
+        /**
+         * Returns the width of the document.
+         * @method getDocumentWidth
+         * @return {Int} The width of the actual document (which includes the body and its margin).
+         */
+        getDocumentWidth: function() {
+            var scrollWidth = (document.compatMode != 'CSS1Compat') ? document.body.scrollWidth : document.documentElement.scrollWidth;
+            var w = Math.max(scrollWidth, Y.Dom.getViewportWidth());
+            return w;
+        },
+
+        /**
+         * Returns the current height of the viewport.
+         * @method getViewportHeight
+         * @return {Int} The height of the viewable area of the page (excludes scrollbars).
+         */
+        getViewportHeight: function() {
+            var height = self.innerHeight; // Safari, Opera
+            var mode = document.compatMode;
+        
+            if ( (mode || isIE) && !isOpera ) { // IE, Gecko
+                height = (mode == 'CSS1Compat') ?
+                        document.documentElement.clientHeight : // Standards
+                        document.body.clientHeight; // Quirks
+            }
+        
+            return height;
+        },
+        
+        /**
+         * Returns the current width of the viewport.
+         * @method getViewportWidth
+         * @return {Int} The width of the viewable area of the page (excludes scrollbars).
+         */
+        
+        getViewportWidth: function() {
+            var width = self.innerWidth;  // Safari
+            var mode = document.compatMode;
+            
+            if (mode || isIE) { // IE, Gecko, Opera
+                width = (mode == 'CSS1Compat') ?
+                        document.documentElement.clientWidth : // Standards
+                        document.body.clientWidth; // Quirks
+            }
+            return width;
+        }
+    };
+})();
+/**
+ * A region is a representation of an object on a grid.  It is defined
+ * by the top, right, bottom, left extents, so is rectangular by default.  If 
+ * other shapes are required, this class could be extended to support it.
+ * @namespace YAHOO.util
+ * @class Region
+ * @param {Int} t the top extent
+ * @param {Int} r the right extent
+ * @param {Int} b the bottom extent
+ * @param {Int} l the left extent
+ * @constructor
+ */
+YAHOO.util.Region = function(t, r, b, l) {
+
+    /**
+     * The region's top extent
+     * @property top
+     * @type Int
+     */
+    this.top = t;
+    
+    /**
+     * The region's top extent as index, for symmetry with set/getXY
+     * @property 1
+     * @type Int
+     */
+    this[1] = t;
+
+    /**
+     * The region's right extent
+     * @property right
+     * @type int
+     */
+    this.right = r;
+
+    /**
+     * The region's bottom extent
+     * @property bottom
+     * @type Int
+     */
+    this.bottom = b;
+
+    /**
+     * The region's left extent
+     * @property left
+     * @type Int
+     */
+    this.left = l;
+    
+    /**
+     * The region's left extent as index, for symmetry with set/getXY
+     * @property 0
+     * @type Int
+     */
+    this[0] = l;
+};
+
+/**
+ * Returns true if this region contains the region passed in
+ * @method contains
+ * @param  {Region}  region The region to evaluate
+ * @return {Boolean}        True if the region is contained with this region, 
+ *                          else false
+ */
+YAHOO.util.Region.prototype.contains = function(region) {
+    return ( region.left   >= this.left   && 
+             region.right  <= this.right  && 
+             region.top    >= this.top    && 
+             region.bottom <= this.bottom    );
+
+};
+
+/**
+ * Returns the area of the region
+ * @method getArea
+ * @return {Int} the region's area
+ */
+YAHOO.util.Region.prototype.getArea = function() {
+    return ( (this.bottom - this.top) * (this.right - this.left) );
+};
+
+/**
+ * Returns the region where the passed in region overlaps with this one
+ * @method intersect
+ * @param  {Region} region The region that intersects
+ * @return {Region}        The overlap region, or null if there is no overlap
+ */
+YAHOO.util.Region.prototype.intersect = function(region) {
+    var t = Math.max( this.top,    region.top    );
+    var r = Math.min( this.right,  region.right  );
+    var b = Math.min( this.bottom, region.bottom );
+    var l = Math.max( this.left,   region.left   );
+    
+    if (b >= t && r >= l) {
+        return new YAHOO.util.Region(t, r, b, l);
+    } else {
+        return null;
+    }
+};
+
+/**
+ * Returns the region representing the smallest region that can contain both
+ * the passed in region and this region.
+ * @method union
+ * @param  {Region} region The region that to create the union with
+ * @return {Region}        The union region
+ */
+YAHOO.util.Region.prototype.union = function(region) {
+    var t = Math.min( this.top,    region.top    );
+    var r = Math.max( this.right,  region.right  );
+    var b = Math.max( this.bottom, region.bottom );
+    var l = Math.min( this.left,   region.left   );
+
+    return new YAHOO.util.Region(t, r, b, l);
+};
+
+/**
+ * toString
+ * @method toString
+ * @return string the region properties
+ */
+YAHOO.util.Region.prototype.toString = function() {
+    return ( "Region {"    +
+             "top: "       + this.top    + 
+             ", right: "   + this.right  + 
+             ", bottom: "  + this.bottom + 
+             ", left: "    + this.left   + 
+             "}" );
+};
+
+/**
+ * Returns a region that is occupied by the DOM element
+ * @method getRegion
+ * @param  {HTMLElement} el The element
+ * @return {Region}         The region that the element occupies
+ * @static
+ */
+YAHOO.util.Region.getRegion = function(el) {
+    var p = YAHOO.util.Dom.getXY(el);
+
+    var t = p[1];
+    var r = p[0] + el.offsetWidth;
+    var b = p[1] + el.offsetHeight;
+    var l = p[0];
+
+    return new YAHOO.util.Region(t, r, b, l);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * A point is a region that is special in that it represents a single point on 
+ * the grid.
+ * @namespace YAHOO.util
+ * @class Point
+ * @param {Int} x The X position of the point
+ * @param {Int} y The Y position of the point
+ * @constructor
+ * @extends YAHOO.util.Region
+ */
+YAHOO.util.Point = function(x, y) {
+   if (x instanceof Array) { // accept output from Dom.getXY
+      y = x[1];
+      x = x[0];
+   }
+   
+    /**
+     * The X position of the point, which is also the right, left and index zero (for Dom.getXY symmetry)
+     * @property x
+     * @type Int
+     */
+
+    this.x = this.right = this.left = this[0] = x;
+     
+    /**
+     * The Y position of the point, which is also the top, bottom and index one (for Dom.getXY symmetry)
+     * @property y
+     * @type Int
+     */
+    this.y = this.top = this.bottom = this[1] = y;
+};
+
+YAHOO.util.Point.prototype = new YAHOO.util.Region();
+
+YAHOO.register("dom", YAHOO.util.Dom, {version: "2.2.1", build: "193"});

Added: jifty/branches/virtual-models/share/web/static/js/yui/element-beta.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/share/web/static/js/yui/element-beta.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,913 @@
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/**
+ * Provides Attribute configurations.
+ * @namespace YAHOO.util
+ * @class Attribute
+ * @constructor
+ * @param hash {Object} The intial Attribute.
+ * @param {YAHOO.util.AttributeProvider} The owner of the Attribute instance.
+ */
+
+YAHOO.util.Attribute = function(hash, owner) {
+    if (owner) { 
+        this.owner = owner;
+        this.configure(hash, true);
+    }
+};
+
+YAHOO.util.Attribute.prototype = {
+	/**
+     * The name of the attribute.
+	 * @property name
+	 * @type String
+	 */
+    name: undefined,
+    
+	/**
+     * The value of the attribute.
+	 * @property value
+	 * @type String
+	 */
+    value: null,
+    
+	/**
+     * The owner of the attribute.
+	 * @property owner
+	 * @type YAHOO.util.AttributeProvider
+	 */
+    owner: null,
+    
+	/**
+     * Whether or not the attribute is read only.
+	 * @property readOnly
+	 * @type Boolean
+	 */
+    readOnly: false,
+    
+	/**
+     * Whether or not the attribute can only be written once.
+	 * @property writeOnce
+	 * @type Boolean
+	 */
+    writeOnce: false,
+
+	/**
+     * The attribute's initial configuration.
+     * @private
+	 * @property _initialConfig
+	 * @type Object
+	 */
+    _initialConfig: null,
+    
+	/**
+     * Whether or not the attribute's value has been set.
+     * @private
+	 * @property _written
+	 * @type Boolean
+	 */
+    _written: false,
+    
+	/**
+     * The method to use when setting the attribute's value.
+     * The method recieves the new value as the only argument.
+	 * @property method
+	 * @type Function
+	 */
+    method: null,
+    
+	/**
+     * The validator to use when setting the attribute's value.
+	 * @property validator
+	 * @type Function
+     * @return Boolean
+	 */
+    validator: null,
+    
+    /**
+     * Retrieves the current value of the attribute.
+     * @method getValue
+     * @return {any} The current value of the attribute.
+     */
+    getValue: function() {
+        return this.value;
+    },
+    
+    /**
+     * Sets the value of the attribute and fires beforeChange and change events.
+     * @method setValue
+     * @param {Any} value The value to apply to the attribute.
+     * @param {Boolean} silent If true the change events will not be fired.
+     * @return {Boolean} Whether or not the value was set.
+     */
+    setValue: function(value, silent) {
+        var beforeRetVal;
+        var owner = this.owner;
+        var name = this.name;
+        
+        var event = {
+            type: name, 
+            prevValue: this.getValue(),
+            newValue: value
+        };
+        
+        if (this.readOnly || ( this.writeOnce && this._written) ) {
+            return false; // write not allowed
+        }
+        
+        if (this.validator && !this.validator.call(owner, value) ) {
+            return false; // invalid value
+        }
+
+        if (!silent) {
+            beforeRetVal = owner.fireBeforeChangeEvent(event);
+            if (beforeRetVal === false) {
+                return false;
+            }
+        }
+
+        if (this.method) {
+            this.method.call(owner, value);
+        }
+        
+        this.value = value;
+        this._written = true;
+        
+        event.type = name;
+        
+        if (!silent) {
+            this.owner.fireChangeEvent(event);
+        }
+        
+        return true;
+    },
+    
+    /**
+     * Allows for configuring the Attribute's properties.
+     * @method configure
+     * @param {Object} map A key-value map of Attribute properties.
+     * @param {Boolean} init Whether or not this should become the initial config.
+     */
+    configure: function(map, init) {
+        map = map || {};
+        this._written = false; // reset writeOnce
+        this._initialConfig = this._initialConfig || {};
+        
+        for (var key in map) {
+            if ( key && YAHOO.lang.hasOwnProperty(map, key) ) {
+                this[key] = map[key];
+                if (init) {
+                    this._initialConfig[key] = map[key];
+                }
+            }
+        }
+    },
+    
+    /**
+     * Resets the value to the initial config value.
+     * @method resetValue
+     * @return {Boolean} Whether or not the value was set.
+     */
+    resetValue: function() {
+        return this.setValue(this._initialConfig.value);
+    },
+    
+    /**
+     * Resets the attribute config to the initial config state.
+     * @method resetConfig
+     */
+    resetConfig: function() {
+        this.configure(this._initialConfig);
+    },
+    
+    /**
+     * Resets the value to the current value.
+     * Useful when values may have gotten out of sync with actual properties.
+     * @method refresh
+     * @return {Boolean} Whether or not the value was set.
+     */
+    refresh: function(silent) {
+        this.setValue(this.value, silent);
+    }
+};
+
+(function() {
+    var Lang = YAHOO.util.Lang;
+
+    /*
+    Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+    Code licensed under the BSD License:
+    http://developer.yahoo.net/yui/license.txt
+    */
+    
+    /**
+     * Provides and manages YAHOO.util.Attribute instances
+     * @namespace YAHOO.util
+     * @class AttributeProvider
+     * @uses YAHOO.util.EventProvider
+     */
+    YAHOO.util.AttributeProvider = function() {};
+    
+    YAHOO.util.AttributeProvider.prototype = {
+        
+        /**
+         * A key-value map of Attribute configurations
+         * @property _configs
+         * @protected (may be used by subclasses and augmentors)
+         * @private
+         * @type {Object}
+         */
+        _configs: null,
+        /**
+         * Returns the current value of the attribute.
+         * @method get
+         * @param {String} key The attribute whose value will be returned.
+         */
+        get: function(key){
+            var configs = this._configs || {};
+            var config = configs[key];
+            
+            if (!config) {
+                return undefined;
+            }
+            
+            return config.value;
+        },
+        
+        /**
+         * Sets the value of a config.
+         * @method set
+         * @param {String} key The name of the attribute
+         * @param {Any} value The value to apply to the attribute
+         * @param {Boolean} silent Whether or not to suppress change events
+         * @return {Boolean} Whether or not the value was set.
+         */
+        set: function(key, value, silent){
+            var configs = this._configs || {};
+            var config = configs[key];
+            
+            if (!config) {
+                return false;
+            }
+            
+            return config.setValue(value, silent);
+        },
+    
+        /**
+         * Returns an array of attribute names.
+         * @method getAttributeKeys
+         * @return {Array} An array of attribute names.
+         */
+        getAttributeKeys: function(){
+            var configs = this._configs;
+            var keys = [];
+            var config;
+            for (var key in configs) {
+                config = configs[key];
+                if ( Lang.hasOwnProperty(configs, key) && 
+                        !Lang.isUndefined(config) ) {
+                    keys[keys.length] = key;
+                }
+            }
+            
+            return keys;
+        },
+        
+        /**
+         * Sets multiple attribute values.
+         * @method setAttributes
+         * @param {Object} map  A key-value map of attributes
+         * @param {Boolean} silent Whether or not to suppress change events
+         */
+        setAttributes: function(map, silent){
+            for (var key in map) {
+                if ( Lang.hasOwnProperty(map, key) ) {
+                    this.set(key, map[key], silent);
+                }
+            }
+        },
+    
+        /**
+         * Resets the specified attribute's value to its initial value.
+         * @method resetValue
+         * @param {String} key The name of the attribute
+         * @param {Boolean} silent Whether or not to suppress change events
+         * @return {Boolean} Whether or not the value was set
+         */
+        resetValue: function(key, silent){
+            var configs = this._configs || {};
+            if (configs[key]) {
+                this.set(key, configs[key]._initialConfig.value, silent);
+                return true;
+            }
+            return false;
+        },
+    
+        /**
+         * Sets the attribute's value to its current value.
+         * @method refresh
+         * @param {String | Array} key The attribute(s) to refresh
+         * @param {Boolean} silent Whether or not to suppress change events
+         */
+        refresh: function(key, silent){
+            var configs = this._configs;
+            
+            key = ( ( Lang.isString(key) ) ? [key] : key ) || 
+                    this.getAttributeKeys();
+            
+            for (var i = 0, len = key.length; i < len; ++i) { 
+                if ( // only set if there is a value and not null
+                    configs[key[i]] && 
+                    ! Lang.isUndefined(configs[key[i]].value) &&
+                    ! Lang.isNull(configs[key[i]].value) ) {
+                    configs[key[i]].refresh(silent);
+                }
+            }
+        },
+    
+        /**
+         * Adds an Attribute to the AttributeProvider instance. 
+         * @method register
+         * @param {String} key The attribute's name
+         * @param {Object} map A key-value map containing the
+         * attribute's properties.
+         * @deprecated Use setAttributeConfig
+         */
+        register: function(key, map) {
+            this.setAttributeConfig(key, map);
+        },
+        
+        
+        /**
+         * Returns the attribute's properties.
+         * @method getAttributeConfig
+         * @param {String} key The attribute's name
+         * @private
+         * @return {object} A key-value map containing all of the
+         * attribute's properties.
+         */
+        getAttributeConfig: function(key) {
+            var configs = this._configs || {};
+            var config = configs[key] || {};
+            var map = {}; // returning a copy to prevent overrides
+            
+            for (key in config) {
+                if ( Lang.hasOwnProperty(config, key) ) {
+                    map[key] = config[key];
+                }
+            }
+    
+            return map;
+        },
+        
+        /**
+         * Sets or updates an Attribute instance's properties. 
+         * @method setAttributeConfig
+         * @param {String} key The attribute's name.
+         * @param {Object} map A key-value map of attribute properties
+         * @param {Boolean} init Whether or not this should become the intial config.
+         */
+        setAttributeConfig: function(key, map, init) {
+            var configs = this._configs || {};
+            map = map || {};
+            if (!configs[key]) {
+                map.name = key;
+                configs[key] = new YAHOO.util.Attribute(map, this);
+            } else {
+                configs[key].configure(map, init);
+            }
+        },
+        
+        /**
+         * Sets or updates an Attribute instance's properties. 
+         * @method configureAttribute
+         * @param {String} key The attribute's name.
+         * @param {Object} map A key-value map of attribute properties
+         * @param {Boolean} init Whether or not this should become the intial config.
+         * @deprecated Use setAttributeConfig
+         */
+        configureAttribute: function(key, map, init) {
+            this.setAttributeConfig(key, map, init);
+        },
+        
+        /**
+         * Resets an attribute to its intial configuration. 
+         * @method resetAttributeConfig
+         * @param {String} key The attribute's name.
+         * @private
+         */
+        resetAttributeConfig: function(key){
+            var configs = this._configs || {};
+            configs[key].resetConfig();
+        },
+        
+        /**
+         * Fires the attribute's beforeChange event. 
+         * @method fireBeforeChangeEvent
+         * @param {String} key The attribute's name.
+         * @param {Obj} e The event object to pass to handlers.
+         */
+        fireBeforeChangeEvent: function(e) {
+            var type = 'before';
+            type += e.type.charAt(0).toUpperCase() + e.type.substr(1) + 'Change';
+            e.type = type;
+            return this.fireEvent(e.type, e);
+        },
+        
+        /**
+         * Fires the attribute's change event. 
+         * @method fireChangeEvent
+         * @param {String} key The attribute's name.
+         * @param {Obj} e The event object to pass to the handlers.
+         */
+        fireChangeEvent: function(e) {
+            e.type += 'Change';
+            return this.fireEvent(e.type, e);
+        }
+    };
+    
+    YAHOO.augment(YAHOO.util.AttributeProvider, YAHOO.util.EventProvider);
+})();
+
+(function() {
+// internal shorthand
+var Dom = YAHOO.util.Dom,
+    AttributeProvider = YAHOO.util.AttributeProvider;
+
+/**
+ * Element provides an wrapper object to simplify adding
+ * event listeners, using dom methods, and managing attributes. 
+ * @module element
+ * @namespace YAHOO.util
+ * @requires yahoo, dom, event
+ * @beta
+ */
+
+/**
+ * Element provides an wrapper object to simplify adding
+ * event listeners, using dom methods, and managing attributes. 
+ * @class Element
+ * @uses YAHOO.util.AttributeProvider
+ * @constructor
+ * @param el {HTMLElement | String} The html element that 
+ * represents the Element.
+ * @param {Object} map A key-value map of initial config names and values
+ */
+YAHOO.util.Element = function(el, map) {
+    if (arguments.length) {
+        this.init(el, map);
+    }
+};
+
+YAHOO.util.Element.prototype = {
+    /**
+     * Dom events supported by the Element instance.
+     * @property DOM_EVENTS
+     * @type Object
+     */
+    DOM_EVENTS: null,
+
+    /**
+     * Wrapper for HTMLElement method.
+     * @method appendChild
+     * @param {Boolean} deep Whether or not to do a deep clone
+     */
+    appendChild: function(child) {
+        child = child.get ? child.get('element') : child;
+        this.get('element').appendChild(child);
+    },
+    
+    /**
+     * Wrapper for HTMLElement method.
+     * @method getElementsByTagName
+     * @param {String} tag The tagName to collect
+     */
+    getElementsByTagName: function(tag) {
+        return this.get('element').getElementsByTagName(tag);
+    },
+    
+    /**
+     * Wrapper for HTMLElement method.
+     * @method hasChildNodes
+     * @return {Boolean} Whether or not the element has childNodes
+     */
+    hasChildNodes: function() {
+        return this.get('element').hasChildNodes();
+    },
+    
+    /**
+     * Wrapper for HTMLElement method.
+     * @method insertBefore
+     * @param {HTMLElement} element The HTMLElement to insert
+     * @param {HTMLElement} before The HTMLElement to insert
+     * the element before.
+     */
+    insertBefore: function(element, before) {
+        element = element.get ? element.get('element') : element;
+        before = (before && before.get) ? before.get('element') : before;
+        
+        this.get('element').insertBefore(element, before);
+    },
+    
+    /**
+     * Wrapper for HTMLElement method.
+     * @method removeChild
+     * @param {HTMLElement} child The HTMLElement to remove
+     */
+    removeChild: function(child) {
+        child = child.get ? child.get('element') : child;
+        this.get('element').removeChild(child);
+        return true;
+    },
+    
+    /**
+     * Wrapper for HTMLElement method.
+     * @method replaceChild
+     * @param {HTMLElement} newNode The HTMLElement to insert
+     * @param {HTMLElement} oldNode The HTMLElement to replace
+     */
+    replaceChild: function(newNode, oldNode) {
+        newNode = newNode.get ? newNode.get('element') : newNode;
+        oldNode = oldNode.get ? oldNode.get('element') : oldNode;
+        return this.get('element').replaceChild(newNode, oldNode);
+    },
+
+    
+    /**
+     * Registers Element specific attributes.
+     * @method initAttributes
+     * @param {Object} map A key-value map of initial attribute configs
+     */
+    initAttributes: function(map) {
+    },
+
+    /**
+     * Adds a listener for the given event.  These may be DOM or 
+     * customEvent listeners.  Any event that is fired via fireEvent
+     * can be listened for.  All handlers receive an event object. 
+     * @method addListener
+     * @param {String} type The name of the event to listen for
+     * @param {Function} fn The handler to call when the event fires
+     * @param {Any} obj A variable to pass to the handler
+     * @param {Object} scope The object to use for the scope of the handler 
+     */
+    addListener: function(type, fn, obj, scope) {
+        var el = this.get('element');
+        scope = scope || this;
+        
+        el = this.get('id') || el;
+        var self = this; 
+        if (!this._events[type]) { // create on the fly
+            if ( this.DOM_EVENTS[type] ) {
+                YAHOO.util.Event.addListener(el, type, function(e) {
+                    if (e.srcElement && !e.target) { // supplement IE with target
+                        e.target = e.srcElement;
+                    }
+                    self.fireEvent(type, e);
+                }, obj, scope);
+            }
+            
+            this.createEvent(type, this);
+            this._events[type] = true;
+        }
+        
+        this.subscribe.apply(this, arguments); // notify via customEvent
+    },
+    
+    
+    /**
+     * Alias for addListener
+     * @method on
+     * @param {String} type The name of the event to listen for
+     * @param {Function} fn The function call when the event fires
+     * @param {Any} obj A variable to pass to the handler
+     * @param {Object} scope The object to use for the scope of the handler 
+     */
+    on: function() { this.addListener.apply(this, arguments); },
+    
+    
+    /**
+     * Remove an event listener
+     * @method removeListener
+     * @param {String} type The name of the event to listen for
+     * @param {Function} fn The function call when the event fires
+     */
+    removeListener: function(type, fn) {
+        this.unsubscribe.apply(this, arguments);
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method addClass
+     * @param {String} className The className to add
+     */
+    addClass: function(className) {
+        Dom.addClass(this.get('element'), className);
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method getElementsByClassName
+     * @param {String} className The className to collect
+     * @param {String} tag (optional) The tag to use in
+     * conjunction with class name
+     * @return {Array} Array of HTMLElements
+     */
+    getElementsByClassName: function(className, tag) {
+        return Dom.getElementsByClassName(className, tag,
+                this.get('element') );
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method hasClass
+     * @param {String} className The className to add
+     * @return {Boolean} Whether or not the element has the class name
+     */
+    hasClass: function(className) {
+        return Dom.hasClass(this.get('element'), className); 
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method removeClass
+     * @param {String} className The className to remove
+     */
+    removeClass: function(className) {
+        return Dom.removeClass(this.get('element'), className);
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method replaceClass
+     * @param {String} oldClassName The className to replace
+     * @param {String} newClassName The className to add
+     */
+    replaceClass: function(oldClassName, newClassName) {
+        return Dom.replaceClass(this.get('element'), 
+                oldClassName, newClassName);
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method setStyle
+     * @param {String} property The style property to set
+     * @param {String} value The value to apply to the style property
+     */
+    setStyle: function(property, value) {
+        var el = this.get('element');
+        if (!el) {
+            return this._queue[this._queue.length] = ['setStyle', arguments];
+        }
+
+        return Dom.setStyle(el,  property, value); // TODO: always queuing?
+    },
+    
+    /**
+     * Wrapper for Dom method.
+     * @method getStyle
+     * @param {String} property The style property to retrieve
+     * @return {String} The current value of the property
+     */
+    getStyle: function(property) {
+        return Dom.getStyle(this.get('element'),  property);
+    },
+    
+    /**
+     * Apply any queued set calls.
+     * @method fireQueue
+     */
+    fireQueue: function() {
+        var queue = this._queue;
+        for (var i = 0, len = queue.length; i < len; ++i) {
+            this[queue[i][0]].apply(this, queue[i][1]);
+        }
+    },
+    
+    /**
+     * Appends the HTMLElement into either the supplied parentNode.
+     * @method appendTo
+     * @param {HTMLElement | Element} parentNode The node to append to
+     * @param {HTMLElement | Element} before An optional node to insert before
+     */
+    appendTo: function(parent, before) {
+        parent = (parent.get) ?  parent.get('element') : Dom.get(parent);
+        
+        this.fireEvent('beforeAppendTo', {
+            type: 'beforeAppendTo',
+            target: parent
+        });
+        
+        
+        before = (before && before.get) ? 
+                before.get('element') : Dom.get(before);
+        var element = this.get('element');
+        
+        if (!element) {
+            return false;
+        }
+        
+        if (!parent) {
+            return false;
+        }
+        
+        if (element.parent != parent) {
+            if (before) {
+                parent.insertBefore(element, before);
+            } else {
+                parent.appendChild(element);
+            }
+        }
+        
+        
+        this.fireEvent('appendTo', {
+            type: 'appendTo',
+            target: parent
+        });
+    },
+    
+    get: function(key) {
+        var configs = this._configs || {};
+        var el = configs.element; // avoid loop due to 'element'
+        if (el && !configs[key] && !YAHOO.lang.isUndefined(el.value[key]) ) {
+            return el.value[key];
+        }
+
+        return AttributeProvider.prototype.get.call(this, key);
+    },
+
+    set: function(key, value, silent) {
+        var el = this.get('element');
+        if (!el) {
+            this._queue[this._queue.length] = ['set', arguments];
+            if (this._configs[key]) {
+                this._configs[key].value = value; // so "get" works while queueing
+            
+            }
+            return;
+        }
+        
+        // set it on the element if not configured and is an HTML attribute
+        if ( !this._configs[key] && !YAHOO.lang.isUndefined(el[key]) ) {
+            _registerHTMLAttr.call(this, key);
+        }
+
+        return AttributeProvider.prototype.set.apply(this, arguments);
+    },
+    
+    setAttributeConfig: function(key, map, init) {
+        var el = this.get('element');
+
+        if (el && !this._configs[key] && !YAHOO.lang.isUndefined(el[key]) ) {
+            _registerHTMLAttr.call(this, key, map);
+        } else {
+            AttributeProvider.prototype.setAttributeConfig.apply(this, arguments);
+        }
+    },
+    
+    getAttributeKeys: function() {
+        var el = this.get('element');
+        var keys = AttributeProvider.prototype.getAttributeKeys.call(this);
+        
+        //add any unconfigured element keys
+        for (var key in el) {
+            if (!this._configs[key]) {
+                keys[key] = keys[key] || el[key];
+            }
+        }
+        
+        return keys;
+    },
+    
+    init: function(el, attr) {
+        _initElement.apply(this, arguments); 
+    }
+};
+
+var _initElement = function(el, attr) {
+    this._queue = this._queue || [];
+    this._events = this._events || {};
+    this._configs = this._configs || {};
+    attr = attr || {};
+    attr.element = attr.element || el || null;
+
+    this.DOM_EVENTS = {
+        'click': true,
+        'dblclick': true,
+        'keydown': true,
+        'keypress': true,
+        'keyup': true,
+        'mousedown': true,
+        'mousemove': true,
+        'mouseout': true, 
+        'mouseover': true, 
+        'mouseup': true,
+        'focus': true,
+        'blur': true,
+        'submit': true
+    };
+
+    if (YAHOO.lang.isString(el) ) { // defer until available/ready
+        _registerHTMLAttr.call(this, 'id', { value: attr.element });
+    }
+
+    if (Dom.get(el)) {
+        _availableHandler.call(this, attr);  
+        _readyHandler.call(this, attr);
+        return; // note return
+    } 
+
+    YAHOO.util.Event.onAvailable(attr.element, function() {
+        _availableHandler.call(this, attr);  
+    }, this, true);
+    
+    YAHOO.util.Event.onContentReady(attr.element, function() {
+        _readyHandler.call(this, attr);
+    }, this, true);
+};
+
+var _availableHandler = function(attr) {
+    attr.element = Dom.get(attr.element);
+
+    /**
+     * The HTMLElement the Element instance refers to.
+     * @config element
+     * @type HTMLElement
+     */
+    this.setAttributeConfig('element', {
+        value: attr.element,
+        readOnly: true
+     });
+
+    this.fireEvent('available', {
+        type: 'available',
+        target: attr.element
+    }); 
+};
+
+var _readyHandler = function(attr) {
+    this.initAttributes(attr);
+    this.setAttributes(attr, true);
+    this.fireQueue();
+
+    this.fireEvent('contentReady', {
+        type: 'contentReady',
+        target: attr.element
+    });
+};
+
+/**
+ * Sets the value of the property and fires beforeChange and change events.
+ * @private
+ * @method _registerHTMLAttr
+ * @param {YAHOO.util.Element} element The Element instance to
+ * register the config to.
+ * @param {String} key The name of the config to register
+ * @param {Object} map A key-value map of the config's params
+ */
+var _registerHTMLAttr = function(key, map) {
+    var el = this.get('element');
+    map = map || {};
+    map.name = key;
+    map.method = map.method || function(value) {
+        el[key] = value;
+    };
+    map.value = map.value || el[key];
+    this._configs[key] = new YAHOO.util.Attribute(map, this);
+};
+
+/**
+ * Fires when the Element's HTMLElement can be retrieved by Id.
+ * <p>See: <a href="#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code>&lt;String&gt; type</code> available<br>
+ * <code>&lt;HTMLElement&gt;
+ * target</code> the HTMLElement bound to this Element instance<br>
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var target = e.target};<br>
+ * myTabs.addListener('available', handler);</code></p>
+ * @event available
+ */
+ 
+/**
+ * Fires when the Element's HTMLElement subtree is rendered.
+ * <p>See: <a href="#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code>&lt;String&gt; type</code> contentReady<br>
+ * <code>&lt;HTMLElement&gt;
+ * target</code> the HTMLElement bound to this Element instance<br>
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var target = e.target};<br>
+ * myTabs.addListener('contentReady', handler);</code></p>
+ * @event contentReady
+ */
+
+
+YAHOO.augment(YAHOO.util.Element, AttributeProvider);
+})();
+
+YAHOO.register("element", YAHOO.util.Element, {version: "2.2.1", build: "193"});

Modified: jifty/branches/virtual-models/share/web/static/js/yui/event.js
==============================================================================
--- jifty/branches/virtual-models/share/web/static/js/yui/event.js	(original)
+++ jifty/branches/virtual-models/share/web/static/js/yui/event.js	Mon May  7 16:28:32 2007
@@ -1,1771 +1,2183 @@
-/*                                                                                                                                                      
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.12.1
-*/ 
-
-/**
- * The CustomEvent class lets you define events for your application
- * that can be subscribed to by one or more independent component.
- *
- * @param {String}  type The type of event, which is passed to the callback
- *                  when the event fires
- * @param {Object}  oScope The context the event will fire from.  "this" will
- *                  refer to this object in the callback.  Default value: 
- *                  the window object.  The listener can override this.
- * @param {boolean} silent pass true to prevent the event from writing to
- *                  the debugsystem
- * @param {int}     signature the signature that the custom event subscriber
- *                  will receive. YAHOO.util.CustomEvent.LIST or 
- *                  YAHOO.util.CustomEvent.FLAT.  The default is
- *                  YAHOO.util.CustomEvent.LIST.
- * @namespace YAHOO.util
- * @class CustomEvent
- * @constructor
- */
-YAHOO.util.CustomEvent = function(type, oScope, silent, signature) {
-
-    /**
-     * The type of event, returned to subscribers when the event fires
-     * @property type
-     * @type string
-     */
-    this.type = type;
-
-    /**
-     * The scope the the event will fire from by default.  Defaults to the window 
-     * obj
-     * @property scope
-     * @type object
-     */
-    this.scope = oScope || window;
-
-    /**
-     * By default all custom events are logged in the debug build, set silent
-     * to true to disable debug outpu for this event.
-     * @property silent
-     * @type boolean
-     */
-    this.silent = silent;
-
-    /**
-     * Custom events support two styles of arguments provided to the event
-     * subscribers.  
-     * <ul>
-     * <li>YAHOO.util.CustomEvent.LIST: 
-     *   <ul>
-     *   <li>param1: event name</li>
-     *   <li>param2: array of arguments sent to fire</li>
-     *   <li>param3: <optional> a custom object supplied by the subscriber</li>
-     *   </ul>
-     * </li>
-     * <li>YAHOO.util.CustomEvent.FLAT
-     *   <ul>
-     *   <li>param1: the first argument passed to fire.  If you need to
-     *           pass multiple parameters, use and array or object literal</li>
-     *   <li>param2: <optional> a custom object supplied by the subscriber</li>
-     *   </ul>
-     * </li>
-     * </ul>
-     *   @property signature
-     *   @type int
-     */
-    this.signature = signature || YAHOO.util.CustomEvent.LIST;
-
-    /**
-     * The subscribers to this event
-     * @property subscribers
-     * @type Subscriber[]
-     */
-    this.subscribers = [];
-
-    if (!this.silent) {
-    }
-
-    var onsubscribeType = "_YUICEOnSubscribe";
-
-    // Only add subscribe events for events that are not generated by 
-    // CustomEvent
-    if (type !== onsubscribeType) {
-
-        /**
-         * Custom events provide a custom event that fires whenever there is
-         * a new subscriber to the event.  This provides an opportunity to
-         * handle the case where there is a non-repeating event that has
-         * already fired has a new subscriber.  
-         *
-         * @event subscribeEvent
-         * @type YAHOO.util.CustomEvent
-         * @param {Function} fn The function to execute
-         * @param {Object}   obj An object to be passed along when the event 
-         *                       fires
-         * @param {boolean|Object}  override If true, the obj passed in becomes 
-         *                                   the execution scope of the listener.
-         *                                   if an object, that object becomes the
-         *                                   the execution scope.
-         */
-        this.subscribeEvent = 
-                new YAHOO.util.CustomEvent(onsubscribeType, this, true);
-
-    } 
-};
-
-/**
- * Subscriber listener sigature constant.  The LIST type returns three
- * parameters: the event type, the array of args passed to fire, and
- * the optional custom object
- * @property YAHOO.util.CustomEvent.LIST
- * @static
- * @type int
- */
-YAHOO.util.CustomEvent.LIST = 0;
-
-/**
- * Subscriber listener sigature constant.  The FLAT type returns two
- * parameters: the first argument passed to fire and the optional 
- * custom object
- * @property YAHOO.util.CustomEvent.FLAT
- * @static
- * @type int
- */
-YAHOO.util.CustomEvent.FLAT = 1;
-
-YAHOO.util.CustomEvent.prototype = {
-
-    /**
-     * Subscribes the caller to this event
-     * @method subscribe
-     * @param {Function} fn        The function to execute
-     * @param {Object}   obj       An object to be passed along when the event 
-     *                             fires
-     * @param {boolean|Object}  override If true, the obj passed in becomes 
-     *                                   the execution scope of the listener.
-     *                                   if an object, that object becomes the
-     *                                   the execution scope.
-     */
-    subscribe: function(fn, obj, override) {
-        if (this.subscribeEvent) {
-            this.subscribeEvent.fire(fn, obj, override);
-        }
-
-        this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, override) );
-    },
-
-    /**
-     * Unsubscribes the caller from this event
-     * @method unsubscribe
-     * @param {Function} fn  The function to execute
-     * @param {Object}   obj  The custom object passed to subscribe (optional)
-     * @return {boolean} True if the subscriber was found and detached.
-     */
-    unsubscribe: function(fn, obj) {
-        var found = false;
-        for (var i=0, len=this.subscribers.length; i<len; ++i) {
-            var s = this.subscribers[i];
-            if (s && s.contains(fn, obj)) {
-                this._delete(i);
-                found = true;
-            }
-        }
-
-        return found;
-    },
-
-    /**
-     * Notifies the subscribers.  The callback functions will be executed
-     * from the scope specified when the event was created, and with the 
-     * following parameters:
-     *   <ul>
-     *   <li>The type of event</li>
-     *   <li>All of the arguments fire() was executed with as an array</li>
-     *   <li>The custom object (if any) that was passed into the subscribe() 
-     *       method</li>
-     *   </ul>
-     * @method fire 
-     * @param {Object*} arguments an arbitrary set of parameters to pass to 
-     *                            the handler.
-     * @return {boolean} false if one of the subscribers returned false, 
-     *                   true otherwise
-     */
-    fire: function() {
-        var len=this.subscribers.length;
-        if (!len && this.silent) {
-            return true;
-        }
-
-        var args=[], ret=true, i;
-
-        for (i=0; i<arguments.length; ++i) {
-            args.push(arguments[i]);
-        }
-
-        var argslength = args.length;
-
-        if (!this.silent) {
-        }
-
-        for (i=0; i<len; ++i) {
-            var s = this.subscribers[i];
-            if (s) {
-                if (!this.silent) {
-                }
-
-                var scope = s.getScope(this.scope);
-
-                if (this.signature == YAHOO.util.CustomEvent.FLAT) {
-                    var param = null;
-                    if (args.length > 0) {
-                        param = args[0];
-                    }
-                    ret = s.fn.call(scope, param, s.obj);
-                } else {
-                    ret = s.fn.call(scope, this.type, args, s.obj);
-                }
-                if (false === ret) {
-                    if (!this.silent) {
-                    }
-
-                    //break;
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    },
-
-    /**
-     * Removes all listeners
-     * @method unsubscribeAll
-     */
-    unsubscribeAll: function() {
-        for (var i=0, len=this.subscribers.length; i<len; ++i) {
-            this._delete(len - 1 - i);
-        }
-    },
-
-    /**
-     * @method _delete
-     * @private
-     */
-    _delete: function(index) {
-        var s = this.subscribers[index];
-        if (s) {
-            delete s.fn;
-            delete s.obj;
-        }
-
-        // delete this.subscribers[index];
-        this.subscribers.splice(index, 1);
-    },
-
-    /**
-     * @method toString
-     */
-    toString: function() {
-         return "CustomEvent: " + "'" + this.type  + "', " + 
-             "scope: " + this.scope;
-
-    }
-};
-
-/////////////////////////////////////////////////////////////////////
-
-/**
- * Stores the subscriber information to be used when the event fires.
- * @param {Function} fn       The function to execute
- * @param {Object}   obj      An object to be passed along when the event fires
- * @param {boolean}  override If true, the obj passed in becomes the execution
- *                            scope of the listener
- * @class Subscriber
- * @constructor
- */
-YAHOO.util.Subscriber = function(fn, obj, override) {
-
-    /**
-     * The callback that will be execute when the event fires
-     * @property fn
-     * @type function
-     */
-    this.fn = fn;
-
-    /**
-     * An optional custom object that will passed to the callback when
-     * the event fires
-     * @property obj
-     * @type object
-     */
-    this.obj = obj || null;
-
-    /**
-     * The default execution scope for the event listener is defined when the
-     * event is created (usually the object which contains the event).
-     * By setting override to true, the execution scope becomes the custom
-     * object passed in by the subscriber.  If override is an object, that 
-     * object becomes the scope.
-     * @property override
-     * @type boolean|object
-     */
-    this.override = override;
-
-};
-
-/**
- * Returns the execution scope for this listener.  If override was set to true
- * the custom obj will be the scope.  If override is an object, that is the
- * scope, otherwise the default scope will be used.
- * @method getScope
- * @param {Object} defaultScope the scope to use if this listener does not
- *                              override it.
- */
-YAHOO.util.Subscriber.prototype.getScope = function(defaultScope) {
-    if (this.override) {
-        if (this.override === true) {
-            return this.obj;
-        } else {
-            return this.override;
-        }
-    }
-    return defaultScope;
-};
-
-/**
- * Returns true if the fn and obj match this objects properties.
- * Used by the unsubscribe method to match the right subscriber.
- *
- * @method contains
- * @param {Function} fn the function to execute
- * @param {Object} obj an object to be passed along when the event fires
- * @return {boolean} true if the supplied arguments match this 
- *                   subscriber's signature.
- */
-YAHOO.util.Subscriber.prototype.contains = function(fn, obj) {
-    if (obj) {
-        return (this.fn == fn && this.obj == obj);
-    } else {
-        return (this.fn == fn);
-    }
-};
-
-/**
- * @method toString
- */
-YAHOO.util.Subscriber.prototype.toString = function() {
-    return "Subscriber { obj: " + (this.obj || "")  + 
-           ", override: " +  (this.override || "no") + " }";
-};
-
-/**
- * The Event Utility provides utilities for managing DOM Events and tools
- * for building event systems
- *
- * @module event
- * @title Event Utility
- * @namespace YAHOO.util
- * @requires yahoo
- */
-
-// The first instance of Event will win if it is loaded more than once.
-if (!YAHOO.util.Event) {
-
-/**
- * The event utility provides functions to add and remove event listeners,
- * event cleansing.  It also tries to automatically remove listeners it
- * registers during the unload event.
- *
- * @class Event
- * @static
- */
-    YAHOO.util.Event = function() {
-
-        /**
-         * True after the onload event has fired
-         * @property loadComplete
-         * @type boolean
-         * @static
-         * @private
-         */
-        var loadComplete =  false;
-
-        /**
-         * Cache of wrapped listeners
-         * @property listeners
-         * @type array
-         * @static
-         * @private
-         */
-        var listeners = [];
-
-        /**
-         * User-defined unload function that will be fired before all events
-         * are detached
-         * @property unloadListeners
-         * @type array
-         * @static
-         * @private
-         */
-        var unloadListeners = [];
-
-        /**
-         * Cache of DOM0 event handlers to work around issues with DOM2 events
-         * in Safari
-         * @property legacyEvents
-         * @static
-         * @private
-         */
-        var legacyEvents = [];
-
-        /**
-         * Listener stack for DOM0 events
-         * @property legacyHandlers
-         * @static
-         * @private
-         */
-        var legacyHandlers = [];
-
-        /**
-         * The number of times to poll after window.onload.  This number is
-         * increased if additional late-bound handlers are requested after
-         * the page load.
-         * @property retryCount
-         * @static
-         * @private
-         */
-        var retryCount = 0;
-
-        /**
-         * onAvailable listeners
-         * @property onAvailStack
-         * @static
-         * @private
-         */
-        var onAvailStack = [];
-
-        /**
-         * Lookup table for legacy events
-         * @property legacyMap
-         * @static
-         * @private
-         */
-        var legacyMap = [];
-
-        /**
-         * Counter for auto id generation
-         * @property counter
-         * @static
-         * @private
-         */
-        var counter = 0;
-
-        return { // PREPROCESS
-
-            /**
-             * The number of times we should look for elements that are not
-             * in the DOM at the time the event is requested after the document
-             * has been loaded.  The default is 200 at amp;50 ms, so it will poll
-             * for 10 seconds or until all outstanding handlers are bound
-             * (whichever comes first).
-             * @property POLL_RETRYS
-             * @type int
-             * @static
-             * @final
-             */
-            POLL_RETRYS: 200,
-
-            /**
-             * The poll interval in milliseconds
-             * @property POLL_INTERVAL
-             * @type int
-             * @static
-             * @final
-             */
-            POLL_INTERVAL: 20,
-
-            /**
-             * Element to bind, int constant
-             * @property EL
-             * @type int
-             * @static
-             * @final
-             */
-            EL: 0,
-
-            /**
-             * Type of event, int constant
-             * @property TYPE
-             * @type int
-             * @static
-             * @final
-             */
-            TYPE: 1,
-
-            /**
-             * Function to execute, int constant
-             * @property FN
-             * @type int
-             * @static
-             * @final
-             */
-            FN: 2,
-
-            /**
-             * Function wrapped for scope correction and cleanup, int constant
-             * @property WFN
-             * @type int
-             * @static
-             * @final
-             */
-            WFN: 3,
-
-            /**
-             * Object passed in by the user that will be returned as a 
-             * parameter to the callback, int constant
-             * @property OBJ
-             * @type int
-             * @static
-             * @final
-             */
-            OBJ: 3,
-
-            /**
-             * Adjusted scope, either the element we are registering the event
-             * on or the custom object passed in by the listener, int constant
-             * @property ADJ_SCOPE
-             * @type int
-             * @static
-             * @final
-             */
-            ADJ_SCOPE: 4,
-
-            /**
-             * Safari detection is necessary to work around the preventDefault
-             * bug that makes it so you can't cancel a href click from the 
-             * handler.  There is not a capabilities check we can use here.
-             * @property isSafari
-             * @private
-             * @static
-             */
-            isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),
-
-            /**
-             * IE detection needed to properly calculate pageX and pageY.  
-             * capabilities checking didn't seem to work because another 
-             * browser that does not provide the properties have the values 
-             * calculated in a different manner than IE.
-             * @property isIE
-             * @private
-             * @static
-             */
-            isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) && 
-                    navigator.userAgent.match(/msie/gi)),
-
-            /**
-             * poll handle
-             * @property _interval
-             * @private
-             */
-            _interval: null,
-
-            /**
-             * @method startInterval
-             * @static
-             * @private
-             */
-            startInterval: function() {
-                if (!this._interval) {
-                    var self = this;
-                    var callback = function() { self._tryPreloadAttach(); };
-                    this._interval = setInterval(callback, this.POLL_INTERVAL);
-                    // this.timeout = setTimeout(callback, i);
-                }
-            },
-
-            /**
-             * Executes the supplied callback when the item with the supplied
-             * id is found.  This is meant to be used to execute behavior as
-             * soon as possible as the page loads.  If you use this after the
-             * initial page load it will poll for a fixed time for the element.
-             * The number of times it will poll and the frequency are
-             * configurable.  By default it will poll for 10 seconds.
-             *
-             * @method onAvailable
-             *
-             * @param {string}   p_id the id of the element to look for.
-             * @param {function} p_fn what to execute when the element is found.
-             * @param {object}   p_obj an optional object to be passed back as
-             *                   a parameter to p_fn.
-             * @param {boolean}  p_override If set to true, p_fn will execute
-             *                   in the scope of p_obj
-             *
-             * @static
-             */
-            onAvailable: function(p_id, p_fn, p_obj, p_override) {
-                onAvailStack.push( { id:         p_id, 
-                                     fn:         p_fn, 
-                                     obj:        p_obj, 
-                                     override:   p_override, 
-                                     checkReady: false    } );
-
-                retryCount = this.POLL_RETRYS;
-                this.startInterval();
-            },
-
-            /**
-             * Works the same way as onAvailable, but additionally checks the
-             * state of sibling elements to determine if the content of the
-             * available element is safe to modify.
-             *
-             * @method onContentReady
-             *
-             * @param {string}   p_id the id of the element to look for.
-             * @param {function} p_fn what to execute when the element is ready.
-             * @param {object}   p_obj an optional object to be passed back as
-             *                   a parameter to p_fn.
-             * @param {boolean}  p_override If set to true, p_fn will execute
-             *                   in the scope of p_obj
-             *
-             * @static
-             */
-            onContentReady: function(p_id, p_fn, p_obj, p_override) {
-                onAvailStack.push( { id:         p_id, 
-                                     fn:         p_fn, 
-                                     obj:        p_obj, 
-                                     override:   p_override,
-                                     checkReady: true      } );
-
-                retryCount = this.POLL_RETRYS;
-                this.startInterval();
-            },
-
-            /**
-             * Appends an event handler
-             *
-             * @method addListener
-             *
-             * @param {Object}   el        The html element to assign the 
-             *                             event to
-             * @param {String}   sType     The type of event to append
-             * @param {Function} fn        The method the event invokes
-             * @param {Object}   obj    An arbitrary object that will be 
-             *                             passed as a parameter to the handler
-             * @param {boolean}  override  If true, the obj passed in becomes
-             *                             the execution scope of the listener
-             * @return {boolean} True if the action was successful or defered,
-             *                        false if one or more of the elements 
-             *                        could not have the listener attached,
-             *                        or if the operation throws an exception.
-             * @static
-             */
-            addListener: function(el, sType, fn, obj, override) {
-
-                if (!fn || !fn.call) {
-                    return false;
-                }
-
-                // The el argument can be an array of elements or element ids.
-                if ( this._isValidCollection(el)) {
-                    var ok = true;
-                    for (var i=0,len=el.length; i<len; ++i) {
-                        ok = this.on(el[i], 
-                                       sType, 
-                                       fn, 
-                                       obj, 
-                                       override) && ok;
-                    }
-                    return ok;
-
-                } else if (typeof el == "string") {
-                    var oEl = this.getEl(el);
-                    // If the el argument is a string, we assume it is 
-                    // actually the id of the element.  If the page is loaded
-                    // we convert el to the actual element, otherwise we 
-                    // defer attaching the event until onload event fires
-
-                    // check to see if we need to delay hooking up the event 
-                    // until after the page loads.
-                    if (oEl) {
-                        el = oEl;
-                    } else {
-                        // defer adding the event until the element is available
-                        this.onAvailable(el, function() {
-                           YAHOO.util.Event.on(el, sType, fn, obj, override);
-                        });
-
-                        return true;
-                    }
-                }
-
-                // Element should be an html element or an array if we get 
-                // here.
-                if (!el) {
-                    return false;
-                }
-
-                // we need to make sure we fire registered unload events 
-                // prior to automatically unhooking them.  So we hang on to 
-                // these instead of attaching them to the window and fire the
-                // handles explicitly during our one unload event.
-                if ("unload" == sType && obj !== this) {
-                    unloadListeners[unloadListeners.length] =
-                            [el, sType, fn, obj, override];
-                    return true;
-                }
-
-
-                // if the user chooses to override the scope, we use the custom
-                // object passed in, otherwise the executing scope will be the
-                // HTML element that the event is registered on
-                var scope = el;
-                if (override) {
-                    if (override === true) {
-                        scope = obj;
-                    } else {
-                        scope = override;
-                    }
-                }
-
-                // wrap the function so we can return the obj object when
-                // the event fires;
-                var wrappedFn = function(e) {
-                        return fn.call(scope, YAHOO.util.Event.getEvent(e), 
-                                obj);
-                    };
-
-                var li = [el, sType, fn, wrappedFn, scope];
-                var index = listeners.length;
-                // cache the listener so we can try to automatically unload
-                listeners[index] = li;
-
-                if (this.useLegacyEvent(el, sType)) {
-                    var legacyIndex = this.getLegacyIndex(el, sType);
-
-                    // Add a new dom0 wrapper if one is not detected for this
-                    // element
-                    if ( legacyIndex == -1 || 
-                                el != legacyEvents[legacyIndex][0] ) {
-
-                        legacyIndex = legacyEvents.length;
-                        legacyMap[el.id + sType] = legacyIndex;
-
-                        // cache the signature for the DOM0 event, and 
-                        // include the existing handler for the event, if any
-                        legacyEvents[legacyIndex] = 
-                            [el, sType, el["on" + sType]];
-                        legacyHandlers[legacyIndex] = [];
-
-                        el["on" + sType] = 
-                            function(e) {
-                                YAHOO.util.Event.fireLegacyEvent(
-                                    YAHOO.util.Event.getEvent(e), legacyIndex);
-                            };
-                    }
-
-                    // add a reference to the wrapped listener to our custom
-                    // stack of events
-                    //legacyHandlers[legacyIndex].push(index);
-                    legacyHandlers[legacyIndex].push(li);
-
-                } else {
-                    try {
-                        this._simpleAdd(el, sType, wrappedFn, false);
-                    } catch(e) {
-                        // handle an error trying to attach an event.  If it fails
-                        // we need to clean up the cache
-                        this.removeListener(el, sType, fn);
-                        return false;
-                    }
-                }
-
-                return true;
-                
-            },
-
-            /**
-             * When using legacy events, the handler is routed to this object
-             * so we can fire our custom listener stack.
-             * @method fireLegacyEvent
-             * @static
-             * @private
-             */
-            fireLegacyEvent: function(e, legacyIndex) {
-                var ok = true;
-
-                var le = legacyHandlers[legacyIndex];
-                for (var i=0,len=le.length; i<len; ++i) {
-                    var li = le[i];
-                    if ( li && li[this.WFN] ) {
-                        var scope = li[this.ADJ_SCOPE];
-                        var ret = li[this.WFN].call(scope, e);
-                        ok = (ok && ret);
-                    }
-                }
-
-                return ok;
-            },
-
-            /**
-             * Returns the legacy event index that matches the supplied 
-             * signature
-             * @method getLegacyIndex
-             * @static
-             * @private
-             */
-            getLegacyIndex: function(el, sType) {
-                var key = this.generateId(el) + sType;
-                if (typeof legacyMap[key] == "undefined") { 
-                    return -1;
-                } else {
-                    return legacyMap[key];
-                }
-            },
-
-            /**
-             * Logic that determines when we should automatically use legacy
-             * events instead of DOM2 events.
-             * @method useLegacyEvent
-             * @static
-             * @private
-             */
-            useLegacyEvent: function(el, sType) {
-                if (!el.addEventListener && !el.attachEvent) {
-                    return true;
-                } else if (this.isSafari) {
-                    if ("click" == sType || "dblclick" == sType) {
-                        return true;
-                    }
-                }
-                return false;
-            },
-                    
-            /**
-             * Removes an event handler
-             *
-             * @method removeListener
-             *
-             * @param {Object} el the html element or the id of the element to 
-             * assign the event to.
-             * @param {String} sType the type of event to remove.
-             * @param {Function} fn the method the event invokes.  If fn is
-             * undefined, then all event handlers for the type of event are 
-             * removed.
-             * @return {boolean} true if the unbind was successful, false 
-             * otherwise.
-             * @static
-             */
-            removeListener: function(el, sType, fn) {
-                var i, len;
-
-                // The el argument can be a string
-                if (typeof el == "string") {
-                    el = this.getEl(el);
-                // The el argument can be an array of elements or element ids.
-                } else if ( this._isValidCollection(el)) {
-                    var ok = true;
-                    for (i=0,len=el.length; i<len; ++i) {
-                        ok = ( this.removeListener(el[i], sType, fn) && ok );
-                    }
-                    return ok;
-                }
-
-                if (!fn || !fn.call) {
-                    //return false;
-                    return this.purgeElement(el, false, sType);
-                }
-
-                if ("unload" == sType) {
-
-                    for (i=0, len=unloadListeners.length; i<len; i++) {
-                        var li = unloadListeners[i];
-                        if (li && 
-                            li[0] == el && 
-                            li[1] == sType && 
-                            li[2] == fn) {
-                                unloadListeners.splice(i, 1);
-                                return true;
-                        }
-                    }
-
-                    return false;
-                }
-
-                var cacheItem = null;
-
-                // The index is a hidden parameter; needed to remove it from
-                // the method signature because it was tempting users to
-                // try and take advantage of it, which is not possible.
-                var index = arguments[3];
-  
-                if ("undefined" == typeof index) {
-                    index = this._getCacheIndex(el, sType, fn);
-                }
-
-                if (index >= 0) {
-                    cacheItem = listeners[index];
-                }
-
-                if (!el || !cacheItem) {
-                    return false;
-                }
-
-
-                if (this.useLegacyEvent(el, sType)) {
-                    var legacyIndex = this.getLegacyIndex(el, sType);
-                    var llist = legacyHandlers[legacyIndex];
-                    if (llist) {
-                        for (i=0, len=llist.length; i<len; ++i) {
-                            li = llist[i];
-                            if (li && 
-                                li[this.EL] == el && 
-                                li[this.TYPE] == sType && 
-                                li[this.FN] == fn) {
-                                    llist.splice(i, 1);
-                                    break;
-                            }
-                        }
-                    }
-
-                } else {
-                    try {
-                        this._simpleRemove(el, sType, cacheItem[this.WFN], false);
-                    } catch(e) {
-                        return false;
-                    }
-                }
-
-                // removed the wrapped handler
-                delete listeners[index][this.WFN];
-                delete listeners[index][this.FN];
-                listeners.splice(index, 1);
-
-                return true;
-
-            },
-
-            /**
-             * Returns the event's target element
-             * @method getTarget
-             * @param {Event} ev the event
-             * @param {boolean} resolveTextNode when set to true the target's
-             *                  parent will be returned if the target is a 
-             *                  text node.  @deprecated, the text node is
-             *                  now resolved automatically
-             * @return {HTMLElement} the event's target
-             * @static
-             */
-            getTarget: function(ev, resolveTextNode) {
-                var t = ev.target || ev.srcElement;
-                return this.resolveTextNode(t);
-            },
-
-            /**
-             * In some cases, some browsers will return a text node inside
-             * the actual element that was targeted.  This normalizes the
-             * return value for getTarget and getRelatedTarget.
-             * @method resolveTextNode
-             * @param {HTMLElement} node node to resolve
-             * @return {HTMLElement} the normized node
-             * @static
-             */
-            resolveTextNode: function(node) {
-                // if (node && node.nodeName && 
-                        // "#TEXT" == node.nodeName.toUpperCase()) {
-                if (node && 3 == node.nodeType) {
-                    return node.parentNode;
-                } else {
-                    return node;
-                }
-            },
-
-            /**
-             * Returns the event's pageX
-             * @method getPageX
-             * @param {Event} ev the event
-             * @return {int} the event's pageX
-             * @static
-             */
-            getPageX: function(ev) {
-                var x = ev.pageX;
-                if (!x && 0 !== x) {
-                    x = ev.clientX || 0;
-
-                    if ( this.isIE ) {
-                        x += this._getScrollLeft();
-                    }
-                }
-
-                return x;
-            },
-
-            /**
-             * Returns the event's pageY
-             * @method getPageY
-             * @param {Event} ev the event
-             * @return {int} the event's pageY
-             * @static
-             */
-            getPageY: function(ev) {
-                var y = ev.pageY;
-                if (!y && 0 !== y) {
-                    y = ev.clientY || 0;
-
-                    if ( this.isIE ) {
-                        y += this._getScrollTop();
-                    }
-                }
-
-                return y;
-            },
-
-            /**
-             * Returns the pageX and pageY properties as an indexed array.
-             * @method getXY
-             * @type int[]
-             * @static
-             */
-            getXY: function(ev) {
-                return [this.getPageX(ev), this.getPageY(ev)];
-            },
-
-            /**
-             * Returns the event's related target 
-             * @method getRelatedTarget
-             * @param {Event} ev the event
-             * @return {HTMLElement} the event's relatedTarget
-             * @static
-             */
-            getRelatedTarget: function(ev) {
-                var t = ev.relatedTarget;
-                if (!t) {
-                    if (ev.type == "mouseout") {
-                        t = ev.toElement;
-                    } else if (ev.type == "mouseover") {
-                        t = ev.fromElement;
-                    }
-                }
-
-                return this.resolveTextNode(t);
-            },
-
-            /**
-             * Returns the time of the event.  If the time is not included, the
-             * event is modified using the current time.
-             * @method getTime
-             * @param {Event} ev the event
-             * @return {Date} the time of the event
-             * @static
-             */
-            getTime: function(ev) {
-                if (!ev.time) {
-                    var t = new Date().getTime();
-                    try {
-                        ev.time = t;
-                    } catch(e) { 
-                        return t;
-                    }
-                }
-
-                return ev.time;
-            },
-
-            /**
-             * Convenience method for stopPropagation + preventDefault
-             * @method stopEvent
-             * @param {Event} ev the event
-             * @static
-             */
-            stopEvent: function(ev) {
-                this.stopPropagation(ev);
-                this.preventDefault(ev);
-            },
-
-            /**
-             * Stops event propagation
-             * @method stopPropagation
-             * @param {Event} ev the event
-             * @static
-             */
-            stopPropagation: function(ev) {
-                if (ev.stopPropagation) {
-                    ev.stopPropagation();
-                } else {
-                    ev.cancelBubble = true;
-                }
-            },
-
-            /**
-             * Prevents the default behavior of the event
-             * @method preventDefault
-             * @param {Event} ev the event
-             * @static
-             */
-            preventDefault: function(ev) {
-                if (ev.preventDefault) {
-                    ev.preventDefault();
-                } else {
-                    ev.returnValue = false;
-                }
-            },
-             
-            /**
-             * Finds the event in the window object, the caller's arguments, or
-             * in the arguments of another method in the callstack.  This is
-             * executed automatically for events registered through the event
-             * manager, so the implementer should not normally need to execute
-             * this function at all.
-             * @method getEvent
-             * @param {Event} e the event parameter from the handler
-             * @return {Event} the event 
-             * @static
-             */
-            getEvent: function(e) {
-                var ev = e || window.event;
-
-                if (!ev) {
-                    var c = this.getEvent.caller;
-                    while (c) {
-                        ev = c.arguments[0];
-                        if (ev && Event == ev.constructor) {
-                            break;
-                        }
-                        c = c.caller;
-                    }
-                }
-
-                return ev;
-            },
-
-            /**
-             * Returns the charcode for an event
-             * @method getCharCode
-             * @param {Event} ev the event
-             * @return {int} the event's charCode
-             * @static
-             */
-            getCharCode: function(ev) {
-                return ev.charCode || ev.keyCode || 0;
-            },
-
-            /**
-             * Locating the saved event handler data by function ref
-             *
-             * @method _getCacheIndex
-             * @static
-             * @private
-             */
-            _getCacheIndex: function(el, sType, fn) {
-                for (var i=0,len=listeners.length; i<len; ++i) {
-                    var li = listeners[i];
-                    if ( li                 && 
-                         li[this.FN] == fn  && 
-                         li[this.EL] == el  && 
-                         li[this.TYPE] == sType ) {
-                        return i;
-                    }
-                }
-
-                return -1;
-            },
-
-            /**
-             * Generates an unique ID for the element if it does not already 
-             * have one.
-             * @method generateId
-             * @param el the element to create the id for
-             * @return {string} the resulting id of the element
-             * @static
-             */
-            generateId: function(el) {
-                var id = el.id;
-
-                if (!id) {
-                    id = "yuievtautoid-" + counter;
-                    ++counter;
-                    el.id = id;
-                }
-
-                return id;
-            },
-
-            /**
-             * We want to be able to use getElementsByTagName as a collection
-             * to attach a group of events to.  Unfortunately, different 
-             * browsers return different types of collections.  This function
-             * tests to determine if the object is array-like.  It will also 
-             * fail if the object is an array, but is empty.
-             * @method _isValidCollection
-             * @param o the object to test
-             * @return {boolean} true if the object is array-like and populated
-             * @static
-             * @private
-             */
-            _isValidCollection: function(o) {
-                // this.logger.debug(o.constructor.toString())
-                // this.logger.debug(typeof o)
-
-                return ( o                    && // o is something
-                         o.length             && // o is indexed
-                         typeof o != "string" && // o is not a string
-                         !o.tagName           && // o is not an HTML element
-                         !o.alert             && // o is not a window
-                         typeof o[0] != "undefined" );
-
-            },
-
-            /**
-             * @private
-             * @property elCache
-             * DOM element cache
-             * @static
-             */
-            elCache: {},
-
-            /**
-             * We cache elements bound by id because when the unload event 
-             * fires, we can no longer use document.getElementById
-             * @method getEl
-             * @static
-             * @private
-             */
-            getEl: function(id) {
-                return document.getElementById(id);
-            },
-
-            /**
-             * Clears the element cache
-             * @deprecated Elements are not cached any longer
-             * @method clearCache
-             * @static
-             * @private
-             */
-            clearCache: function() { },
-
-            /**
-             * hook up any deferred listeners
-             * @method _load
-             * @static
-             * @private
-             */
-            _load: function(e) {
-                loadComplete = true;
-                var EU = YAHOO.util.Event;
-                // Remove the listener to assist with the IE memory issue, but not
-                // for other browsers because FF 1.0x does not like it.
-                if (this.isIE) {
-                    EU._simpleRemove(window, "load", EU._load);
-                }
-            },
-
-            /**
-             * Polling function that runs before the onload event fires, 
-             * attempting to attach to DOM Nodes as soon as they are 
-             * available
-             * @method _tryPreloadAttach
-             * @static
-             * @private
-             */
-            _tryPreloadAttach: function() {
-
-                if (this.locked) {
-                    return false;
-                }
-
-                this.locked = true;
-
-
-                // keep trying until after the page is loaded.  We need to 
-                // check the page load state prior to trying to bind the 
-                // elements so that we can be certain all elements have been 
-                // tested appropriately
-                var tryAgain = !loadComplete;
-                if (!tryAgain) {
-                    tryAgain = (retryCount > 0);
-                }
-
-                // onAvailable
-                var notAvail = [];
-                for (var i=0,len=onAvailStack.length; i<len ; ++i) {
-                    var item = onAvailStack[i];
-                    if (item) {
-                        var el = this.getEl(item.id);
-
-                        if (el) {
-                            // The element is available, but not necessarily ready
-                            // @todo verify IE7 compatibility
-                            // @todo should we test parentNode.nextSibling?
-                            // @todo re-evaluate global content ready
-                            if ( !item.checkReady || 
-                                    loadComplete || 
-                                    el.nextSibling ||
-                                    (document && document.body) ) {
-
-                                var scope = el;
-                                if (item.override) {
-                                    if (item.override === true) {
-                                        scope = item.obj;
-                                    } else {
-                                        scope = item.override;
-                                    }
-                                }
-                                item.fn.call(scope, item.obj);
-                                //delete onAvailStack[i];
-                                // null out instead of delete for Opera
-                                onAvailStack[i] = null;
-                            }
-                        } else {
-                            notAvail.push(item);
-                        }
-                    }
-                }
-
-                retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
-
-                if (tryAgain) {
-                    onAvailStack = notAvail; // cleanse the array
-                    this.startInterval();
-                } else {
-                    clearInterval(this._interval);
-                    this._interval = null;
-                }
-
-                this.locked = false;
-
-                return true;
-
-            },
-
-            /**
-             * Removes all listeners attached to the given element via addListener.
-             * Optionally, the node's children can also be purged.
-             * Optionally, you can specify a specific type of event to remove.
-             * @method purgeElement
-             * @param {HTMLElement} el the element to purge
-             * @param {boolean} recurse recursively purge this element's children
-             * as well.  Use with caution.
-             * @param {string} sType optional type of listener to purge. If
-             * left out, all listeners will be removed
-             * @static
-             */
-            purgeElement: function(el, recurse, sType) {
-                var elListeners = this.getListeners(el, sType);
-                if (elListeners) {
-                    for (var i=0,len=elListeners.length; i<len ; ++i) {
-                        var l = elListeners[i];
-                        // can't use the index on the changing collection
-                        //this.removeListener(el, l.type, l.fn, l.index);
-                        this.removeListener(el, l.type, l.fn);
-                    }
-                }
-
-                if (recurse && el && el.childNodes) {
-                    for (i=0,len=el.childNodes.length; i<len ; ++i) {
-                        this.purgeElement(el.childNodes[i], recurse, sType);
-                    }
-                }
-            },
-
-            /**
-             * Returns all listeners attached to the given element via addListener.
-             * Optionally, you can specify a specific type of event to return.
-             * @method getListeners
-             * @param el {HTMLElement} the element to inspect 
-             * @param sType {string} optional type of listener to return. If
-             * left out, all listeners will be returned
-             * @return {Object} the listener. Contains the following fields:
-             * &nbsp;&nbsp;type:   (string)   the type of event
-             * &nbsp;&nbsp;fn:     (function) the callback supplied to addListener
-             * &nbsp;&nbsp;obj:    (object)   the custom object supplied to addListener
-             * &nbsp;&nbsp;adjust: (boolean)  whether or not to adjust the default scope
-             * &nbsp;&nbsp;index:  (int)      its position in the Event util listener cache
-             * @static
-             */           
-            getListeners: function(el, sType) {
-                var elListeners = [];
-                if (listeners && listeners.length > 0) {
-                    for (var i=0,len=listeners.length; i<len ; ++i) {
-                        var l = listeners[i];
-                        if ( l  && l[this.EL] === el && 
-                                (!sType || sType === l[this.TYPE]) ) {
-                            elListeners.push({
-                                type:   l[this.TYPE],
-                                fn:     l[this.FN],
-                                obj:    l[this.OBJ],
-                                adjust: l[this.ADJ_SCOPE],
-                                index:  i
-                            });
-                        }
-                    }
-                }
-
-                return (elListeners.length) ? elListeners : null;
-            },
-
-            /**
-             * Removes all listeners registered by pe.event.  Called 
-             * automatically during the unload event.
-             * @method _unload
-             * @static
-             * @private
-             */
-            _unload: function(e) {
-
-                var EU = YAHOO.util.Event, i, j, l, len, index;
-
-                for (i=0,len=unloadListeners.length; i<len; ++i) {
-                    l = unloadListeners[i];
-                    if (l) {
-                        var scope = window;
-                        if (l[EU.ADJ_SCOPE]) {
-                            if (l[EU.ADJ_SCOPE] === true) {
-                                scope = l[EU.OBJ];
-                            } else {
-                                scope = l[EU.ADJ_SCOPE];
-                            }
-                        }
-                        l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ] );
-                        unloadListeners[i] = null;
-                        l=null;
-                        scope=null;
-                    }
-                }
-
-                unloadListeners = null;
-
-                if (listeners && listeners.length > 0) {
-                    j = listeners.length;
-                    while (j) {
-                        index = j-1;
-                        l = listeners[index];
-                        if (l) {
-                            EU.removeListener(l[EU.EL], l[EU.TYPE], 
-                                    l[EU.FN], index);
-                        } 
-                        j = j - 1;
-                    }
-                    l=null;
-
-                    EU.clearCache();
-                }
-
-                for (i=0,len=legacyEvents.length; i<len; ++i) {
-                    // dereference the element
-                    //delete legacyEvents[i][0];
-                    legacyEvents[i][0] = null;
-
-                    // delete the array item
-                    //delete legacyEvents[i];
-                    legacyEvents[i] = null;
-                }
-
-                legacyEvents = null;
-
-                EU._simpleRemove(window, "unload", EU._unload);
-
-            },
-
-            /**
-             * Returns scrollLeft
-             * @method _getScrollLeft
-             * @static
-             * @private
-             */
-            _getScrollLeft: function() {
-                return this._getScroll()[1];
-            },
-
-            /**
-             * Returns scrollTop
-             * @method _getScrollTop
-             * @static
-             * @private
-             */
-            _getScrollTop: function() {
-                return this._getScroll()[0];
-            },
-
-            /**
-             * Returns the scrollTop and scrollLeft.  Used to calculate the 
-             * pageX and pageY in Internet Explorer
-             * @method _getScroll
-             * @static
-             * @private
-             */
-            _getScroll: function() {
-                var dd = document.documentElement, db = document.body;
-                if (dd && (dd.scrollTop || dd.scrollLeft)) {
-                    return [dd.scrollTop, dd.scrollLeft];
-                } else if (db) {
-                    return [db.scrollTop, db.scrollLeft];
-                } else {
-                    return [0, 0];
-                }
-            },
-
-            /**
-             * Adds a DOM event directly without the caching, cleanup, scope adj, etc
-             *
-             * @method _simpleAdd
-             * @param {HTMLElement} el      the element to bind the handler to
-             * @param {string}      sType   the type of event handler
-             * @param {function}    fn      the callback to invoke
-             * @param {boolen}      capture capture or bubble phase
-             * @static
-             * @private
-             */
-            _simpleAdd: function () {
-                if (window.addEventListener) {
-                    return function(el, sType, fn, capture) {
-                        el.addEventListener(sType, fn, (capture));
-                    };
-                } else if (window.attachEvent) {
-                    return function(el, sType, fn, capture) {
-                        el.attachEvent("on" + sType, fn);
-                    };
-                } else {
-                    return function(){};
-                }
-            }(),
-
-            /**
-             * Basic remove listener
-             *
-             * @method _simpleRemove
-             * @param {HTMLElement} el      the element to bind the handler to
-             * @param {string}      sType   the type of event handler
-             * @param {function}    fn      the callback to invoke
-             * @param {boolen}      capture capture or bubble phase
-             * @static
-             * @private
-             */
-            _simpleRemove: function() {
-                if (window.removeEventListener) {
-                    return function (el, sType, fn, capture) {
-                        el.removeEventListener(sType, fn, (capture));
-                    };
-                } else if (window.detachEvent) {
-                    return function (el, sType, fn) {
-                        el.detachEvent("on" + sType, fn);
-                    };
-                } else {
-                    return function(){};
-                }
-            }()
-        };
-
-    }();
-
-    (function() {
-        var EU = YAHOO.util.Event;
-
-        /**
-         * YAHOO.util.Event.on is an alias for addListener
-         * @method on
-         * @see addListener
-         * @static
-         */
-        EU.on = EU.addListener;
-
-        // YAHOO.mix(EU, YAHOO.util.EventProvider.prototype);
-        // EU.createEvent("DOMContentReady");
-        // EU.subscribe("DOMContentReady", EU._load);
-
-        if (document && document.body) {
-            EU._load();
-        } else {
-            // EU._simpleAdd(document, "DOMContentLoaded", EU._load);
-            EU._simpleAdd(window, "load", EU._load);
-        }
-        EU._simpleAdd(window, "unload", EU._unload);
-        EU._tryPreloadAttach();
-    })();
-}
-
-/**
- * EventProvider is designed to be used with YAHOO.augment to wrap 
- * CustomEvents in an interface that allows events to be subscribed to 
- * and fired by name.  This makes it possible for implementing code to
- * subscribe to an event that either has not been created yet, or will
- * not be created at all.
- *
- * @Class EventProvider
- */
-YAHOO.util.EventProvider = function() { };
-
-YAHOO.util.EventProvider.prototype = {
-
-    /**
-     * Private storage of custom events
-     * @property __yui_events
-     * @type Object[]
-     * @private
-     */
-    __yui_events: null,
-
-    /**
-     * Private storage of custom event subscribers
-     * @property __yui_subscribers
-     * @type Object[]
-     * @private
-     */
-    __yui_subscribers: null,
-    
-    /**
-     * Subscribe to a CustomEvent by event type
-     *
-     * @method subscribe
-     * @param p_type     {string}   the type, or name of the event
-     * @param p_fn       {function} the function to exectute when the event fires
-     * @param p_obj
-     * @param p_obj      {Object}   An object to be passed along when the event 
-     *                              fires
-     * @param p_override {boolean}  If true, the obj passed in becomes the 
-     *                              execution scope of the listener
-     */
-    subscribe: function(p_type, p_fn, p_obj, p_override) {
-
-        this.__yui_events = this.__yui_events || {};
-        var ce = this.__yui_events[p_type];
-
-        if (ce) {
-            ce.subscribe(p_fn, p_obj, p_override);
-        } else {
-            this.__yui_subscribers = this.__yui_subscribers || {};
-            var subs = this.__yui_subscribers;
-            if (!subs[p_type]) {
-                subs[p_type] = [];
-            }
-            subs[p_type].push(
-                { fn: p_fn, obj: p_obj, override: p_override } );
-        }
-    },
-
-    /**
-     * Unsubscribes the from the specified event
-     * @method unsubscribe
-     * @param p_type {string}   The type, or name of the event
-     * @param p_fn   {Function} The function to execute
-     * @param p_obj  {Object}   The custom object passed to subscribe (optional)
-     * @return {boolean} true if the subscriber was found and detached.
-     */
-    unsubscribe: function(p_type, p_fn, p_obj) {
-        this.__yui_events = this.__yui_events || {};
-        var ce = this.__yui_events[p_type];
-        if (ce) {
-            return ce.unsubscribe(p_fn, p_obj);
-        } else {
-            return false;
-        }
-    },
-
-    /**
-     * Creates a new custom event of the specified type.  If a custom event
-     * by that name already exists, it will not be re-created.  In either
-     * case the custom event is returned. 
-     *
-     * @method createEvent
-     *
-     * @param p_type {string} the type, or name of the event
-     * @param p_config {object} optional config params.  Valid properties are:
-     *
-     *  <ul>
-     *    <li>
-     *      scope: defines the default execution scope.  If not defined
-     *      the default scope will be this instance.
-     *    </li>
-     *    <li>
-     *      silent: if true, the custom event will not generate log messages.
-     *      This is false by default.
-     *    </li>
-     *    <li>
-     *      onSubscribeCallback: specifies a callback to execute when the
-     *      event has a new subscriber.  This will fire immediately for
-     *      each queued subscriber if any exist prior to the creation of
-     *      the event.
-     *    </li>
-     *  </ul>
-     *
-     *  @return {CustomEvent} the custom event
-     *
-     */
-    createEvent: function(p_type, p_config) {
-
-        this.__yui_events = this.__yui_events || {};
-        var opts = p_config || {};
-        var events = this.__yui_events;
-
-        if (events[p_type]) {
-        } else {
-
-            var scope  = opts.scope  || this;
-            var silent = opts.silent || null;
-
-            var ce = new YAHOO.util.CustomEvent(p_type, scope, silent,
-                    YAHOO.util.CustomEvent.FLAT);
-            events[p_type] = ce;
-
-            if (opts.onSubscribeCallback) {
-                ce.subscribeEvent.subscribe(opts.onSubscribeCallback);
-            }
-
-            this.__yui_subscribers = this.__yui_subscribers || {};
-            var qs = this.__yui_subscribers[p_type];
-
-            if (qs) {
-                for (var i=0; i<qs.length; ++i) {
-                    ce.subscribe(qs[i].fn, qs[i].obj, qs[i].override);
-                }
-            }
-        }
-
-        return events[p_type];
-    },
-
-   /**
-     * Fire a custom event by name.  The callback functions will be executed
-     * from the scope specified when the event was created, and with the 
-     * following parameters:
-     *   <ul>
-     *   <li>The first argument fire() was executed with</li>
-     *   <li>The custom object (if any) that was passed into the subscribe() 
-     *       method</li>
-     *   </ul>
-     * @method fireEvent
-     * @param p_type    {string}  the type, or name of the event
-     * @param arguments {Object*} an arbitrary set of parameters to pass to 
-     *                            the handler.
-     * @return {boolean} the return value from CustomEvent.fire, or null if 
-     *                   the custom event does not exist.
-     */
-    fireEvent: function(p_type, arg1, arg2, etc) {
-
-        this.__yui_events = this.__yui_events || {};
-        var ce = this.__yui_events[p_type];
-
-        if (ce) {
-            var args = [];
-            for (var i=1; i<arguments.length; ++i) {
-                args.push(arguments[i]);
-            }
-            return ce.fire.apply(ce, args);
-        } else {
-            return null;
-        }
-    },
-
-    /**
-     * Returns true if the custom event of the provided type has been created
-     * with createEvent.
-     * @method hasEvent
-     * @param type {string} the type, or name of the event
-     */
-    hasEvent: function(type) {
-        if (this.__yui_events) {
-            if (this.__yui_events[type]) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-};
-
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+
+/**
+ * The CustomEvent class lets you define events for your application
+ * that can be subscribed to by one or more independent component.
+ *
+ * @param {String}  type The type of event, which is passed to the callback
+ *                  when the event fires
+ * @param {Object}  oScope The context the event will fire from.  "this" will
+ *                  refer to this object in the callback.  Default value: 
+ *                  the window object.  The listener can override this.
+ * @param {boolean} silent pass true to prevent the event from writing to
+ *                  the debugsystem
+ * @param {int}     signature the signature that the custom event subscriber
+ *                  will receive. YAHOO.util.CustomEvent.LIST or 
+ *                  YAHOO.util.CustomEvent.FLAT.  The default is
+ *                  YAHOO.util.CustomEvent.LIST.
+ * @namespace YAHOO.util
+ * @class CustomEvent
+ * @constructor
+ */
+YAHOO.util.CustomEvent = function(type, oScope, silent, signature) {
+
+    /**
+     * The type of event, returned to subscribers when the event fires
+     * @property type
+     * @type string
+     */
+    this.type = type;
+
+    /**
+     * The scope the the event will fire from by default.  Defaults to the window 
+     * obj
+     * @property scope
+     * @type object
+     */
+    this.scope = oScope || window;
+
+    /**
+     * By default all custom events are logged in the debug build, set silent
+     * to true to disable debug outpu for this event.
+     * @property silent
+     * @type boolean
+     */
+    this.silent = silent;
+
+    /**
+     * Custom events support two styles of arguments provided to the event
+     * subscribers.  
+     * <ul>
+     * <li>YAHOO.util.CustomEvent.LIST: 
+     *   <ul>
+     *   <li>param1: event name</li>
+     *   <li>param2: array of arguments sent to fire</li>
+     *   <li>param3: <optional> a custom object supplied by the subscriber</li>
+     *   </ul>
+     * </li>
+     * <li>YAHOO.util.CustomEvent.FLAT
+     *   <ul>
+     *   <li>param1: the first argument passed to fire.  If you need to
+     *           pass multiple parameters, use and array or object literal</li>
+     *   <li>param2: <optional> a custom object supplied by the subscriber</li>
+     *   </ul>
+     * </li>
+     * </ul>
+     *   @property signature
+     *   @type int
+     */
+    this.signature = signature || YAHOO.util.CustomEvent.LIST;
+
+    /**
+     * The subscribers to this event
+     * @property subscribers
+     * @type Subscriber[]
+     */
+    this.subscribers = [];
+
+    if (!this.silent) {
+    }
+
+    var onsubscribeType = "_YUICEOnSubscribe";
+
+    // Only add subscribe events for events that are not generated by 
+    // CustomEvent
+    if (type !== onsubscribeType) {
+
+        /**
+         * Custom events provide a custom event that fires whenever there is
+         * a new subscriber to the event.  This provides an opportunity to
+         * handle the case where there is a non-repeating event that has
+         * already fired has a new subscriber.  
+         *
+         * @event subscribeEvent
+         * @type YAHOO.util.CustomEvent
+         * @param {Function} fn The function to execute
+         * @param {Object}   obj An object to be passed along when the event 
+         *                       fires
+         * @param {boolean|Object}  override If true, the obj passed in becomes 
+         *                                   the execution scope of the listener.
+         *                                   if an object, that object becomes the
+         *                                   the execution scope.
+         */
+        this.subscribeEvent = 
+                new YAHOO.util.CustomEvent(onsubscribeType, this, true);
+
+    } 
+};
+
+/**
+ * Subscriber listener sigature constant.  The LIST type returns three
+ * parameters: the event type, the array of args passed to fire, and
+ * the optional custom object
+ * @property YAHOO.util.CustomEvent.LIST
+ * @static
+ * @type int
+ */
+YAHOO.util.CustomEvent.LIST = 0;
+
+/**
+ * Subscriber listener sigature constant.  The FLAT type returns two
+ * parameters: the first argument passed to fire and the optional 
+ * custom object
+ * @property YAHOO.util.CustomEvent.FLAT
+ * @static
+ * @type int
+ */
+YAHOO.util.CustomEvent.FLAT = 1;
+
+YAHOO.util.CustomEvent.prototype = {
+
+    /**
+     * Subscribes the caller to this event
+     * @method subscribe
+     * @param {Function} fn        The function to execute
+     * @param {Object}   obj       An object to be passed along when the event 
+     *                             fires
+     * @param {boolean|Object}  override If true, the obj passed in becomes 
+     *                                   the execution scope of the listener.
+     *                                   if an object, that object becomes the
+     *                                   the execution scope.
+     */
+    subscribe: function(fn, obj, override) {
+
+        if (!fn) {
+throw new Error("Invalid callback for subscriber to '" + this.type + "'");
+        }
+
+        if (this.subscribeEvent) {
+            this.subscribeEvent.fire(fn, obj, override);
+        }
+
+        this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, override) );
+    },
+
+    /**
+     * Unsubscribes subscribers.
+     * @method unsubscribe
+     * @param {Function} fn  The subscribed function to remove, if not supplied
+     *                       all will be removed
+     * @param {Object}   obj  The custom object passed to subscribe.  This is
+     *                        optional, but if supplied will be used to
+     *                        disambiguate multiple listeners that are the same
+     *                        (e.g., you subscribe many object using a function
+     *                        that lives on the prototype)
+     * @return {boolean} True if the subscriber was found and detached.
+     */
+    unsubscribe: function(fn, obj) {
+
+        if (!fn) {
+            return this.unsubscribeAll();
+        }
+
+        var found = false;
+        for (var i=0, len=this.subscribers.length; i<len; ++i) {
+            var s = this.subscribers[i];
+            if (s && s.contains(fn, obj)) {
+                this._delete(i);
+                found = true;
+            }
+        }
+
+        return found;
+    },
+
+    /**
+     * Notifies the subscribers.  The callback functions will be executed
+     * from the scope specified when the event was created, and with the 
+     * following parameters:
+     *   <ul>
+     *   <li>The type of event</li>
+     *   <li>All of the arguments fire() was executed with as an array</li>
+     *   <li>The custom object (if any) that was passed into the subscribe() 
+     *       method</li>
+     *   </ul>
+     * @method fire 
+     * @param {Object*} arguments an arbitrary set of parameters to pass to 
+     *                            the handler.
+     * @return {boolean} false if one of the subscribers returned false, 
+     *                   true otherwise
+     */
+    fire: function() {
+        var len=this.subscribers.length;
+        if (!len && this.silent) {
+            return true;
+        }
+
+        var args=[], ret=true, i;
+
+        for (i=0; i<arguments.length; ++i) {
+            args.push(arguments[i]);
+        }
+
+        var argslength = args.length;
+
+        if (!this.silent) {
+        }
+
+        for (i=0; i<len; ++i) {
+            var s = this.subscribers[i];
+            if (s) {
+                if (!this.silent) {
+                }
+
+                var scope = s.getScope(this.scope);
+
+                if (this.signature == YAHOO.util.CustomEvent.FLAT) {
+                    var param = null;
+                    if (args.length > 0) {
+                        param = args[0];
+                    }
+                    ret = s.fn.call(scope, param, s.obj);
+                } else {
+                    ret = s.fn.call(scope, this.type, args, s.obj);
+                }
+                if (false === ret) {
+                    if (!this.silent) {
+                    }
+
+                    //break;
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    },
+
+    /**
+     * Removes all listeners
+     * @method unsubscribeAll
+     * @return {int} The number of listeners unsubscribed
+     */
+    unsubscribeAll: function() {
+        for (var i=0, len=this.subscribers.length; i<len; ++i) {
+            this._delete(len - 1 - i);
+        }
+
+        return i;
+    },
+
+    /**
+     * @method _delete
+     * @private
+     */
+    _delete: function(index) {
+        var s = this.subscribers[index];
+        if (s) {
+            delete s.fn;
+            delete s.obj;
+        }
+
+        // delete this.subscribers[index];
+        this.subscribers.splice(index, 1);
+    },
+
+    /**
+     * @method toString
+     */
+    toString: function() {
+         return "CustomEvent: " + "'" + this.type  + "', " + 
+             "scope: " + this.scope;
+
+    }
+};
+
+/////////////////////////////////////////////////////////////////////
+
+/**
+ * Stores the subscriber information to be used when the event fires.
+ * @param {Function} fn       The function to execute
+ * @param {Object}   obj      An object to be passed along when the event fires
+ * @param {boolean}  override If true, the obj passed in becomes the execution
+ *                            scope of the listener
+ * @class Subscriber
+ * @constructor
+ */
+YAHOO.util.Subscriber = function(fn, obj, override) {
+
+    /**
+     * The callback that will be execute when the event fires
+     * @property fn
+     * @type function
+     */
+    this.fn = fn;
+
+    /**
+     * An optional custom object that will passed to the callback when
+     * the event fires
+     * @property obj
+     * @type object
+     */
+    this.obj = obj || null;
+
+    /**
+     * The default execution scope for the event listener is defined when the
+     * event is created (usually the object which contains the event).
+     * By setting override to true, the execution scope becomes the custom
+     * object passed in by the subscriber.  If override is an object, that 
+     * object becomes the scope.
+     * @property override
+     * @type boolean|object
+     */
+    this.override = override;
+
+};
+
+/**
+ * Returns the execution scope for this listener.  If override was set to true
+ * the custom obj will be the scope.  If override is an object, that is the
+ * scope, otherwise the default scope will be used.
+ * @method getScope
+ * @param {Object} defaultScope the scope to use if this listener does not
+ *                              override it.
+ */
+YAHOO.util.Subscriber.prototype.getScope = function(defaultScope) {
+    if (this.override) {
+        if (this.override === true) {
+            return this.obj;
+        } else {
+            return this.override;
+        }
+    }
+    return defaultScope;
+};
+
+/**
+ * Returns true if the fn and obj match this objects properties.
+ * Used by the unsubscribe method to match the right subscriber.
+ *
+ * @method contains
+ * @param {Function} fn the function to execute
+ * @param {Object} obj an object to be passed along when the event fires
+ * @return {boolean} true if the supplied arguments match this 
+ *                   subscriber's signature.
+ */
+YAHOO.util.Subscriber.prototype.contains = function(fn, obj) {
+    if (obj) {
+        return (this.fn == fn && this.obj == obj);
+    } else {
+        return (this.fn == fn);
+    }
+};
+
+/**
+ * @method toString
+ */
+YAHOO.util.Subscriber.prototype.toString = function() {
+    return "Subscriber { obj: " + (this.obj || "")  + 
+           ", override: " +  (this.override || "no") + " }";
+};
+
+/**
+ * The Event Utility provides utilities for managing DOM Events and tools
+ * for building event systems
+ *
+ * @module event
+ * @title Event Utility
+ * @namespace YAHOO.util
+ * @requires yahoo
+ */
+
+// The first instance of Event will win if it is loaded more than once.
+// @TODO this needs to be changed so that only the state data that needs to
+// be preserved is kept, while methods are overwritten/added as needed.
+// This means that the module pattern can't be used.
+if (!YAHOO.util.Event) {
+
+/**
+ * The event utility provides functions to add and remove event listeners,
+ * event cleansing.  It also tries to automatically remove listeners it
+ * registers during the unload event.
+ *
+ * @class Event
+ * @static
+ */
+    YAHOO.util.Event = function() {
+
+        /**
+         * True after the onload event has fired
+         * @property loadComplete
+         * @type boolean
+         * @static
+         * @private
+         */
+        var loadComplete =  false;
+
+        /**
+         * True when the document is initially usable
+         * @property DOMReady
+         * @type boolean
+         * @static
+         * @private
+         */
+        var DOMReady = false;
+
+        /**
+         * Cache of wrapped listeners
+         * @property listeners
+         * @type array
+         * @static
+         * @private
+         */
+        var listeners = [];
+
+        /**
+         * User-defined unload function that will be fired before all events
+         * are detached
+         * @property unloadListeners
+         * @type array
+         * @static
+         * @private
+         */
+        var unloadListeners = [];
+
+        /**
+         * Cache of DOM0 event handlers to work around issues with DOM2 events
+         * in Safari
+         * @property legacyEvents
+         * @static
+         * @private
+         */
+        var legacyEvents = [];
+
+        /**
+         * Listener stack for DOM0 events
+         * @property legacyHandlers
+         * @static
+         * @private
+         */
+        var legacyHandlers = [];
+
+        /**
+         * The number of times to poll after window.onload.  This number is
+         * increased if additional late-bound handlers are requested after
+         * the page load.
+         * @property retryCount
+         * @static
+         * @private
+         */
+        var retryCount = 0;
+
+        /**
+         * onAvailable listeners
+         * @property onAvailStack
+         * @static
+         * @private
+         */
+        var onAvailStack = [];
+
+        /**
+         * Lookup table for legacy events
+         * @property legacyMap
+         * @static
+         * @private
+         */
+        var legacyMap = [];
+
+        /**
+         * Counter for auto id generation
+         * @property counter
+         * @static
+         * @private
+         */
+        var counter = 0;
+        
+        /**
+         * addListener/removeListener can throw errors in unexpected scenarios.
+         * These errors are suppressed, the method returns false, and this property
+         * is set
+         * @property lastError
+         * @type Error
+         */
+        var lastError = null;
+
+        return {
+
+            /**
+             * The number of times we should look for elements that are not
+             * in the DOM at the time the event is requested after the document
+             * has been loaded.  The default is 200 at amp;50 ms, so it will poll
+             * for 10 seconds or until all outstanding handlers are bound
+             * (whichever comes first).
+             * @property POLL_RETRYS
+             * @type int
+             * @static
+             * @final
+             */
+            POLL_RETRYS: 200,
+
+            /**
+             * The poll interval in milliseconds
+             * @property POLL_INTERVAL
+             * @type int
+             * @static
+             * @final
+             */
+            POLL_INTERVAL: 10,
+
+            /**
+             * Element to bind, int constant
+             * @property EL
+             * @type int
+             * @static
+             * @final
+             */
+            EL: 0,
+
+            /**
+             * Type of event, int constant
+             * @property TYPE
+             * @type int
+             * @static
+             * @final
+             */
+            TYPE: 1,
+
+            /**
+             * Function to execute, int constant
+             * @property FN
+             * @type int
+             * @static
+             * @final
+             */
+            FN: 2,
+
+            /**
+             * Function wrapped for scope correction and cleanup, int constant
+             * @property WFN
+             * @type int
+             * @static
+             * @final
+             */
+            WFN: 3,
+
+            /**
+             * Object passed in by the user that will be returned as a 
+             * parameter to the callback, int constant
+             * @property OBJ
+             * @type int
+             * @static
+             * @final
+             */
+            OBJ: 3,
+
+            /**
+             * Adjusted scope, either the element we are registering the event
+             * on or the custom object passed in by the listener, int constant
+             * @property ADJ_SCOPE
+             * @type int
+             * @static
+             * @final
+             */
+            ADJ_SCOPE: 4,
+
+            /**
+             * Safari detection is necessary to work around the preventDefault
+             * bug that makes it so you can't cancel a href click from the 
+             * handler.  Since this function has been used outside of this
+             * utility, it was changed to detect all KHTML browser to be more
+             * friendly towards the non-Safari browsers that share the engine.
+             * Internally, the preventDefault bug detection now uses the
+             * webkit property.
+             * @property isSafari
+             * @private
+             * @static
+             * @deprecated
+             */
+            isSafari: (/KHTML/gi).test(navigator.userAgent),
+            
+            /**
+             * If WebKit is detected, we keep track of the version number of
+             * the engine.  The webkit property will contain a string with
+             * the webkit version number if webkit is detected, null
+             * otherwise.
+             * Safari 1.3.2 (312.6): 312.8.1 <-- currently the latest
+             *                       available on Mac OSX 10.3.
+             * Safari 2.0.2: 416 <-- hasOwnProperty introduced
+             * Safari 2.0.4: 418 <-- preventDefault fixed (I believe)
+             * Safari 2.0.4 (419.3): 418.9.1 <-- current release
+             *
+             * http://developer.apple.com/internet/safari/uamatrix.html
+             * @property webkit
+             * @type string
+             * @static
+             */
+            webkit: function() {
+                var v=navigator.userAgent.match(/AppleWebKit\/([^ ]*)/);
+                if (v&&v[1]) {
+                    return v[1];
+                }
+                return null;
+            }(),
+            
+            /**
+             * IE detection needed to properly calculate pageX and pageY.  
+             * capabilities checking didn't seem to work because another 
+             * browser that does not provide the properties have the values 
+             * calculated in a different manner than IE.
+             * @property isIE
+             * @private
+             * @static
+             */
+            isIE: (!this.webkit && !navigator.userAgent.match(/opera/gi) && 
+                    navigator.userAgent.match(/msie/gi)),
+
+            /**
+             * poll handle
+             * @property _interval
+             * @private
+             */
+            _interval: null,
+
+            /**
+             * @method startInterval
+             * @static
+             * @private
+             */
+            startInterval: function() {
+                if (!this._interval) {
+                    var self = this;
+                    var callback = function() { self._tryPreloadAttach(); };
+                    this._interval = setInterval(callback, this.POLL_INTERVAL);
+                }
+            },
+
+            /**
+             * Executes the supplied callback when the item with the supplied
+             * id is found.  This is meant to be used to execute behavior as
+             * soon as possible as the page loads.  If you use this after the
+             * initial page load it will poll for a fixed time for the element.
+             * The number of times it will poll and the frequency are
+             * configurable.  By default it will poll for 10 seconds.
+             *
+             * @method onAvailable
+             *
+             * @param {string}   p_id the id of the element to look for.
+             * @param {function} p_fn what to execute when the element is found.
+             * @param {object}   p_obj an optional object to be passed back as
+             *                   a parameter to p_fn.
+             * @param {boolean}  p_override If set to true, p_fn will execute
+             *                   in the scope of p_obj
+             *
+             * @static
+             */
+            onAvailable: function(p_id, p_fn, p_obj, p_override) {
+                onAvailStack.push( { id:         p_id, 
+                                     fn:         p_fn, 
+                                     obj:        p_obj, 
+                                     override:   p_override, 
+                                     checkReady: false    } );
+                retryCount = this.POLL_RETRYS;
+                this.startInterval();
+            },
+
+            /**
+             * Executes the supplied callback when the DOM is first usable.
+             *
+             * @method onDOMReady
+             *
+             * @param {function} p_fn what to execute when the element is found.
+             * @param {object}   p_obj an optional object to be passed back as
+             *                   a parameter to p_fn.
+             * @param {boolean}  p_scope If set to true, p_fn will execute
+             *                   in the scope of p_obj, if set to an object it
+             *                   will execute in the scope of that object
+             *
+             * @static
+             */
+            onDOMReady: function(p_fn, p_obj, p_override) {
+                this.DOMReadyEvent.subscribe(p_fn, p_obj, p_override);
+            },
+
+            /**
+             * Works the same way as onAvailable, but additionally checks the
+             * state of sibling elements to determine if the content of the
+             * available element is safe to modify.
+             *
+             * @method onContentReady
+             *
+             * @param {string}   p_id the id of the element to look for.
+             * @param {function} p_fn what to execute when the element is ready.
+             * @param {object}   p_obj an optional object to be passed back as
+             *                   a parameter to p_fn.
+             * @param {boolean}  p_override If set to true, p_fn will execute
+             *                   in the scope of p_obj
+             *
+             * @static
+             */
+            onContentReady: function(p_id, p_fn, p_obj, p_override) {
+                onAvailStack.push( { id:         p_id, 
+                                     fn:         p_fn, 
+                                     obj:        p_obj, 
+                                     override:   p_override,
+                                     checkReady: true      } );
+
+                retryCount = this.POLL_RETRYS;
+                this.startInterval();
+            },
+
+            /**
+             * Appends an event handler
+             *
+             * @method addListener
+             *
+             * @param {Object}   el        The html element to assign the 
+             *                             event to
+             * @param {String}   sType     The type of event to append
+             * @param {Function} fn        The method the event invokes
+             * @param {Object}   obj    An arbitrary object that will be 
+             *                             passed as a parameter to the handler
+             * @param {boolean}  override  If true, the obj passed in becomes
+             *                             the execution scope of the listener
+             * @return {boolean} True if the action was successful or defered,
+             *                        false if one or more of the elements 
+             *                        could not have the listener attached,
+             *                        or if the operation throws an exception.
+             * @static
+             */
+            addListener: function(el, sType, fn, obj, override) {
+
+
+                if (!fn || !fn.call) {
+                    return false;
+                }
+
+                // The el argument can be an array of elements or element ids.
+                if ( this._isValidCollection(el)) {
+                    var ok = true;
+                    for (var i=0,len=el.length; i<len; ++i) {
+                        ok = this.on(el[i], 
+                                       sType, 
+                                       fn, 
+                                       obj, 
+                                       override) && ok;
+                    }
+                    return ok;
+
+                } else if (typeof el == "string") {
+                    var oEl = this.getEl(el);
+                    // If the el argument is a string, we assume it is 
+                    // actually the id of the element.  If the page is loaded
+                    // we convert el to the actual element, otherwise we 
+                    // defer attaching the event until onload event fires
+
+                    // check to see if we need to delay hooking up the event 
+                    // until after the page loads.
+                    if (oEl) {
+                        el = oEl;
+                    } else {
+                        // defer adding the event until the element is available
+                        this.onAvailable(el, function() {
+                           YAHOO.util.Event.on(el, sType, fn, obj, override);
+                        });
+
+                        return true;
+                    }
+                }
+
+                // Element should be an html element or an array if we get 
+                // here.
+                if (!el) {
+                    return false;
+                }
+
+                // we need to make sure we fire registered unload events 
+                // prior to automatically unhooking them.  So we hang on to 
+                // these instead of attaching them to the window and fire the
+                // handles explicitly during our one unload event.
+                if ("unload" == sType && obj !== this) {
+                    unloadListeners[unloadListeners.length] =
+                            [el, sType, fn, obj, override];
+                    return true;
+                }
+
+
+                // if the user chooses to override the scope, we use the custom
+                // object passed in, otherwise the executing scope will be the
+                // HTML element that the event is registered on
+                var scope = el;
+                if (override) {
+                    if (override === true) {
+                        scope = obj;
+                    } else {
+                        scope = override;
+                    }
+                }
+
+                // wrap the function so we can return the obj object when
+                // the event fires;
+                var wrappedFn = function(e) {
+                        return fn.call(scope, YAHOO.util.Event.getEvent(e), 
+                                obj);
+                    };
+
+                var li = [el, sType, fn, wrappedFn, scope];
+                var index = listeners.length;
+                // cache the listener so we can try to automatically unload
+                listeners[index] = li;
+
+                if (this.useLegacyEvent(el, sType)) {
+                    var legacyIndex = this.getLegacyIndex(el, sType);
+
+                    // Add a new dom0 wrapper if one is not detected for this
+                    // element
+                    if ( legacyIndex == -1 || 
+                                el != legacyEvents[legacyIndex][0] ) {
+
+                        legacyIndex = legacyEvents.length;
+                        legacyMap[el.id + sType] = legacyIndex;
+
+                        // cache the signature for the DOM0 event, and 
+                        // include the existing handler for the event, if any
+                        legacyEvents[legacyIndex] = 
+                            [el, sType, el["on" + sType]];
+                        legacyHandlers[legacyIndex] = [];
+
+                        el["on" + sType] = 
+                            function(e) {
+                                YAHOO.util.Event.fireLegacyEvent(
+                                    YAHOO.util.Event.getEvent(e), legacyIndex);
+                            };
+                    }
+
+                    // add a reference to the wrapped listener to our custom
+                    // stack of events
+                    //legacyHandlers[legacyIndex].push(index);
+                    legacyHandlers[legacyIndex].push(li);
+
+                } else {
+                    try {
+                        this._simpleAdd(el, sType, wrappedFn, false);
+                    } catch(ex) {
+                        // handle an error trying to attach an event.  If it fails
+                        // we need to clean up the cache
+                        this.lastError = ex;
+                        this.removeListener(el, sType, fn);
+                        return false;
+                    }
+                }
+
+                return true;
+                
+            },
+
+            /**
+             * When using legacy events, the handler is routed to this object
+             * so we can fire our custom listener stack.
+             * @method fireLegacyEvent
+             * @static
+             * @private
+             */
+            fireLegacyEvent: function(e, legacyIndex) {
+                var ok=true,le,lh,li,scope,ret;
+                
+                lh = legacyHandlers[legacyIndex];
+                for (var i=0,len=lh.length; i<len; ++i) {
+                    li = lh[i];
+                    if ( li && li[this.WFN] ) {
+                        scope = li[this.ADJ_SCOPE];
+                        ret = li[this.WFN].call(scope, e);
+                        ok = (ok && ret);
+                    }
+                }
+
+                // Fire the original handler if we replaced one.  We fire this
+                // after the other events to keep stopPropagation/preventDefault
+                // that happened in the DOM0 handler from touching our DOM2
+                // substitute
+                le = legacyEvents[legacyIndex];
+                if (le && le[2]) {
+                    le[2](e);
+                }
+                
+                return ok;
+            },
+
+            /**
+             * Returns the legacy event index that matches the supplied 
+             * signature
+             * @method getLegacyIndex
+             * @static
+             * @private
+             */
+            getLegacyIndex: function(el, sType) {
+                var key = this.generateId(el) + sType;
+                if (typeof legacyMap[key] == "undefined") { 
+                    return -1;
+                } else {
+                    return legacyMap[key];
+                }
+            },
+
+            /**
+             * Logic that determines when we should automatically use legacy
+             * events instead of DOM2 events.  Currently this is limited to old
+             * Safari browsers with a broken preventDefault
+             * @method useLegacyEvent
+             * @static
+             * @private
+             */
+            useLegacyEvent: function(el, sType) {
+                if (this.webkit && ("click"==sType || "dblclick"==sType)) {
+                    var v = parseInt(this.webkit, 10);
+                    if (!isNaN(v) && v<418) {
+                        return true;
+                    }
+                }
+                return false;
+            },
+                    
+            /**
+             * Removes an event handler
+             *
+             * @method removeListener
+             *
+             * @param {Object} el the html element or the id of the element to 
+             * assign the event to.
+             * @param {String} sType the type of event to remove.
+             * @param {Function} fn the method the event invokes.  If fn is
+             * undefined, then all event handlers for the type of event are 
+             * removed.
+             * @return {boolean} true if the unbind was successful, false 
+             * otherwise.
+             * @static
+             */
+            removeListener: function(el, sType, fn) {
+                var i, len;
+
+                // The el argument can be a string
+                if (typeof el == "string") {
+                    el = this.getEl(el);
+                // The el argument can be an array of elements or element ids.
+                } else if ( this._isValidCollection(el)) {
+                    var ok = true;
+                    for (i=0,len=el.length; i<len; ++i) {
+                        ok = ( this.removeListener(el[i], sType, fn) && ok );
+                    }
+                    return ok;
+                }
+
+                if (!fn || !fn.call) {
+                    //return false;
+                    return this.purgeElement(el, false, sType);
+                }
+
+
+                if ("unload" == sType) {
+
+                    for (i=0, len=unloadListeners.length; i<len; i++) {
+                        var li = unloadListeners[i];
+                        if (li && 
+                            li[0] == el && 
+                            li[1] == sType && 
+                            li[2] == fn) {
+                                unloadListeners.splice(i, 1);
+                                return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                var cacheItem = null;
+
+                // The index is a hidden parameter; needed to remove it from
+                // the method signature because it was tempting users to
+                // try and take advantage of it, which is not possible.
+                var index = arguments[3];
+  
+                if ("undefined" == typeof index) {
+                    index = this._getCacheIndex(el, sType, fn);
+                }
+
+                if (index >= 0) {
+                    cacheItem = listeners[index];
+                }
+
+                if (!el || !cacheItem) {
+                    return false;
+                }
+
+
+                if (this.useLegacyEvent(el, sType)) {
+                    var legacyIndex = this.getLegacyIndex(el, sType);
+                    var llist = legacyHandlers[legacyIndex];
+                    if (llist) {
+                        for (i=0, len=llist.length; i<len; ++i) {
+                            li = llist[i];
+                            if (li && 
+                                li[this.EL] == el && 
+                                li[this.TYPE] == sType && 
+                                li[this.FN] == fn) {
+                                    llist.splice(i, 1);
+                                    break;
+                            }
+                        }
+                    }
+
+                } else {
+                    try {
+                        this._simpleRemove(el, sType, cacheItem[this.WFN], false);
+                    } catch(ex) {
+                        this.lastError = ex;
+                        return false;
+                    }
+                }
+
+                // removed the wrapped handler
+                delete listeners[index][this.WFN];
+                delete listeners[index][this.FN];
+                listeners.splice(index, 1);
+
+                return true;
+
+            },
+
+            /**
+             * Returns the event's target element
+             * @method getTarget
+             * @param {Event} ev the event
+             * @param {boolean} resolveTextNode when set to true the target's
+             *                  parent will be returned if the target is a 
+             *                  text node.  @deprecated, the text node is
+             *                  now resolved automatically
+             * @return {HTMLElement} the event's target
+             * @static
+             */
+            getTarget: function(ev, resolveTextNode) {
+                var t = ev.target || ev.srcElement;
+                return this.resolveTextNode(t);
+            },
+
+            /**
+             * In some cases, some browsers will return a text node inside
+             * the actual element that was targeted.  This normalizes the
+             * return value for getTarget and getRelatedTarget.
+             * @method resolveTextNode
+             * @param {HTMLElement} node node to resolve
+             * @return {HTMLElement} the normized node
+             * @static
+             */
+            resolveTextNode: function(node) {
+                // if (node && node.nodeName && 
+                        // "#TEXT" == node.nodeName.toUpperCase()) {
+                if (node && 3 == node.nodeType) {
+                    return node.parentNode;
+                } else {
+                    return node;
+                }
+            },
+
+            /**
+             * Returns the event's pageX
+             * @method getPageX
+             * @param {Event} ev the event
+             * @return {int} the event's pageX
+             * @static
+             */
+            getPageX: function(ev) {
+                var x = ev.pageX;
+                if (!x && 0 !== x) {
+                    x = ev.clientX || 0;
+
+                    if ( this.isIE ) {
+                        x += this._getScrollLeft();
+                    }
+                }
+
+                return x;
+            },
+
+            /**
+             * Returns the event's pageY
+             * @method getPageY
+             * @param {Event} ev the event
+             * @return {int} the event's pageY
+             * @static
+             */
+            getPageY: function(ev) {
+                var y = ev.pageY;
+                if (!y && 0 !== y) {
+                    y = ev.clientY || 0;
+
+                    if ( this.isIE ) {
+                        y += this._getScrollTop();
+                    }
+                }
+
+
+                return y;
+            },
+
+            /**
+             * Returns the pageX and pageY properties as an indexed array.
+             * @method getXY
+             * @param {Event} ev the event
+             * @return {[x, y]} the pageX and pageY properties of the event
+             * @static
+             */
+            getXY: function(ev) {
+                return [this.getPageX(ev), this.getPageY(ev)];
+            },
+
+            /**
+             * Returns the event's related target 
+             * @method getRelatedTarget
+             * @param {Event} ev the event
+             * @return {HTMLElement} the event's relatedTarget
+             * @static
+             */
+            getRelatedTarget: function(ev) {
+                var t = ev.relatedTarget;
+                if (!t) {
+                    if (ev.type == "mouseout") {
+                        t = ev.toElement;
+                    } else if (ev.type == "mouseover") {
+                        t = ev.fromElement;
+                    }
+                }
+
+                return this.resolveTextNode(t);
+            },
+
+            /**
+             * Returns the time of the event.  If the time is not included, the
+             * event is modified using the current time.
+             * @method getTime
+             * @param {Event} ev the event
+             * @return {Date} the time of the event
+             * @static
+             */
+            getTime: function(ev) {
+                if (!ev.time) {
+                    var t = new Date().getTime();
+                    try {
+                        ev.time = t;
+                    } catch(ex) { 
+                        this.lastError = ex;
+                        return t;
+                    }
+                }
+
+                return ev.time;
+            },
+
+            /**
+             * Convenience method for stopPropagation + preventDefault
+             * @method stopEvent
+             * @param {Event} ev the event
+             * @static
+             */
+            stopEvent: function(ev) {
+                this.stopPropagation(ev);
+                this.preventDefault(ev);
+            },
+
+            /**
+             * Stops event propagation
+             * @method stopPropagation
+             * @param {Event} ev the event
+             * @static
+             */
+            stopPropagation: function(ev) {
+                if (ev.stopPropagation) {
+                    ev.stopPropagation();
+                } else {
+                    ev.cancelBubble = true;
+                }
+            },
+
+            /**
+             * Prevents the default behavior of the event
+             * @method preventDefault
+             * @param {Event} ev the event
+             * @static
+             */
+            preventDefault: function(ev) {
+                if (ev.preventDefault) {
+                    ev.preventDefault();
+                } else {
+                    ev.returnValue = false;
+                }
+            },
+             
+            /**
+             * Finds the event in the window object, the caller's arguments, or
+             * in the arguments of another method in the callstack.  This is
+             * executed automatically for events registered through the event
+             * manager, so the implementer should not normally need to execute
+             * this function at all.
+             * @method getEvent
+             * @param {Event} e the event parameter from the handler
+             * @return {Event} the event 
+             * @static
+             */
+            getEvent: function(e) {
+                var ev = e || window.event;
+
+                if (!ev) {
+                    var c = this.getEvent.caller;
+                    while (c) {
+                        ev = c.arguments[0];
+                        if (ev && Event == ev.constructor) {
+                            break;
+                        }
+                        c = c.caller;
+                    }
+                }
+
+                return ev;
+            },
+
+            /**
+             * Returns the charcode for an event
+             * @method getCharCode
+             * @param {Event} ev the event
+             * @return {int} the event's charCode
+             * @static
+             */
+            getCharCode: function(ev) {
+                return ev.charCode || ev.keyCode || 0;
+            },
+
+            /**
+             * Locating the saved event handler data by function ref
+             *
+             * @method _getCacheIndex
+             * @static
+             * @private
+             */
+            _getCacheIndex: function(el, sType, fn) {
+                for (var i=0,len=listeners.length; i<len; ++i) {
+                    var li = listeners[i];
+                    if ( li                 && 
+                         li[this.FN] == fn  && 
+                         li[this.EL] == el  && 
+                         li[this.TYPE] == sType ) {
+                        return i;
+                    }
+                }
+
+                return -1;
+            },
+
+            /**
+             * Generates an unique ID for the element if it does not already 
+             * have one.
+             * @method generateId
+             * @param el the element to create the id for
+             * @return {string} the resulting id of the element
+             * @static
+             */
+            generateId: function(el) {
+                var id = el.id;
+
+                if (!id) {
+                    id = "yuievtautoid-" + counter;
+                    ++counter;
+                    el.id = id;
+                }
+
+                return id;
+            },
+
+
+            /**
+             * We want to be able to use getElementsByTagName as a collection
+             * to attach a group of events to.  Unfortunately, different 
+             * browsers return different types of collections.  This function
+             * tests to determine if the object is array-like.  It will also 
+             * fail if the object is an array, but is empty.
+             * @method _isValidCollection
+             * @param o the object to test
+             * @return {boolean} true if the object is array-like and populated
+             * @static
+             * @private
+             */
+            _isValidCollection: function(o) {
+                return ( o                    && // o is something
+                         o.length             && // o is indexed
+                         typeof o != "string" && // o is not a string
+                         !o.tagName           && // o is not an HTML element
+                         !o.alert             && // o is not a window
+                         typeof o[0] != "undefined" );
+
+            },
+
+            /**
+             * @private
+             * @property elCache
+             * DOM element cache
+             * @static
+             * @deprecated Elements are not cached any longer
+             */
+            elCache: {},
+
+            /**
+             * We cache elements bound by id because when the unload event 
+             * fires, we can no longer use document.getElementById
+             * @method getEl
+             * @static
+             * @private
+             * @deprecated Elements are not cached any longer
+             */
+            getEl: function(id) {
+                return document.getElementById(id);
+            },
+
+            /**
+             * Clears the element cache
+             * @deprecated Elements are not cached any longer
+             * @method clearCache
+             * @static
+             * @private
+             */
+            clearCache: function() { },
+
+            /**
+             * Custom event the fires when the dom is initially usable
+             * @event DOMReadyEvent
+             */
+            DOMReadyEvent: new YAHOO.util.CustomEvent("DOMReady", this),
+
+            /**
+             * hook up any deferred listeners
+             * @method _load
+             * @static
+             * @private
+             */
+            _load: function(e) {
+                if (!loadComplete) {
+                    loadComplete = true;
+                    var EU = YAHOO.util.Event;
+
+                    // just in case DOMReady did not go off for some reason
+                    EU._ready();
+
+                    // Remove the listener to assist with the IE memory issue, but not
+                    // for other browsers because FF 1.0x does not like it.
+                    if (this.isIE) {
+                        EU._simpleRemove(window, "load", EU._load);
+                    }
+                }
+            },
+
+            /**
+             * Fires the DOMReady event listeners the first time the document is
+             * usable.
+             * @method _ready
+             * @static
+             * @private
+             */
+            _ready: function(e) {
+                if (!DOMReady) {
+                    DOMReady=true;
+                    var EU = YAHOO.util.Event;
+
+                    // Fire the content ready custom event
+                    EU.DOMReadyEvent.fire();
+
+                    // Remove the DOMContentLoaded (FF/Opera)
+                    EU._simpleRemove(document, "DOMContentLoaded", EU._ready);
+                }
+            },
+
+            /**
+             * Polling function that runs before the onload event fires, 
+             * attempting to attach to DOM Nodes as soon as they are 
+             * available
+             * @method _tryPreloadAttach
+             * @static
+             * @private
+             */
+            _tryPreloadAttach: function() {
+
+                if (this.locked) {
+                    return false;
+                }
+
+
+                if (this.isIE && !DOMReady) {
+                    return false;
+                }
+
+                this.locked = true;
+
+
+                // keep trying until after the page is loaded.  We need to 
+                // check the page load state prior to trying to bind the 
+                // elements so that we can be certain all elements have been 
+                // tested appropriately
+                var tryAgain = !loadComplete;
+                if (!tryAgain) {
+                    tryAgain = (retryCount > 0);
+                }
+
+                // onAvailable
+                var notAvail = [];
+
+                var executeItem = function (el, item) {
+                    var scope = el;
+                    if (item.override) {
+                        if (item.override === true) {
+                            scope = item.obj;
+                        } else {
+                            scope = item.override;
+                        }
+                    }
+                    item.fn.call(scope, item.obj);
+                };
+
+                var i,len,item,el;
+
+                // onAvailable
+                for (i=0,len=onAvailStack.length; i<len; ++i) {
+                    item = onAvailStack[i];
+                    if (item && !item.checkReady) {
+                        el = this.getEl(item.id);
+                        if (el) {
+                            executeItem(el, item);
+                            onAvailStack[i] = null;
+                        } else {
+                            notAvail.push(item);
+                        }
+                    }
+                }
+
+                // onContentReady
+                for (i=0,len=onAvailStack.length; i<len; ++i) {
+                    item = onAvailStack[i];
+                    if (item && item.checkReady) {
+                        el = this.getEl(item.id);
+
+                        if (el) {
+                            // The element is available, but not necessarily ready
+                            // @todo should we test parentNode.nextSibling?
+                            if (loadComplete || el.nextSibling) {
+                                executeItem(el, item);
+                                onAvailStack[i] = null;
+                            }
+                        } else {
+                            notAvail.push(item);
+                        }
+                    }
+                }
+
+                retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
+
+                if (tryAgain) {
+                    // we may need to strip the nulled out items here
+                    this.startInterval();
+                } else {
+                    clearInterval(this._interval);
+                    this._interval = null;
+                }
+
+                this.locked = false;
+
+                return true;
+
+            },
+
+            /**
+             * Removes all listeners attached to the given element via addListener.
+             * Optionally, the node's children can also be purged.
+             * Optionally, you can specify a specific type of event to remove.
+             * @method purgeElement
+             * @param {HTMLElement} el the element to purge
+             * @param {boolean} recurse recursively purge this element's children
+             * as well.  Use with caution.
+             * @param {string} sType optional type of listener to purge. If
+             * left out, all listeners will be removed
+             * @static
+             */
+            purgeElement: function(el, recurse, sType) {
+                var elListeners = this.getListeners(el, sType);
+                if (elListeners) {
+                    for (var i=0,len=elListeners.length; i<len ; ++i) {
+                        var l = elListeners[i];
+                        // can't use the index on the changing collection
+                        //this.removeListener(el, l.type, l.fn, l.index);
+                        this.removeListener(el, l.type, l.fn);
+                    }
+                }
+
+                if (recurse && el && el.childNodes) {
+                    for (i=0,len=el.childNodes.length; i<len ; ++i) {
+                        this.purgeElement(el.childNodes[i], recurse, sType);
+                    }
+                }
+            },
+
+            /**
+             * Returns all listeners attached to the given element via addListener.
+             * Optionally, you can specify a specific type of event to return.
+             * @method getListeners
+             * @param el {HTMLElement} the element to inspect 
+             * @param sType {string} optional type of listener to return. If
+             * left out, all listeners will be returned
+             * @return {Object} the listener. Contains the following fields:
+             * &nbsp;&nbsp;type:   (string)   the type of event
+             * &nbsp;&nbsp;fn:     (function) the callback supplied to addListener
+             * &nbsp;&nbsp;obj:    (object)   the custom object supplied to addListener
+             * &nbsp;&nbsp;adjust: (boolean)  whether or not to adjust the default scope
+             * &nbsp;&nbsp;index:  (int)      its position in the Event util listener cache
+             * @static
+             */           
+            getListeners: function(el, sType) {
+                var results=[], searchLists;
+                if (!sType) {
+                    searchLists = [listeners, unloadListeners];
+                } else if (sType == "unload") {
+                    searchLists = [unloadListeners];
+                } else {
+                    searchLists = [listeners];
+                }
+
+                for (var j=0;j<searchLists.length; ++j) {
+                    var searchList = searchLists[j];
+                    if (searchList && searchList.length > 0) {
+                        for (var i=0,len=searchList.length; i<len ; ++i) {
+                            var l = searchList[i];
+                            if ( l  && l[this.EL] === el && 
+                                    (!sType || sType === l[this.TYPE]) ) {
+                                results.push({
+                                    type:   l[this.TYPE],
+                                    fn:     l[this.FN],
+                                    obj:    l[this.OBJ],
+                                    adjust: l[this.ADJ_SCOPE],
+                                    index:  i
+                                });
+                            }
+                        }
+                    }
+                }
+
+                return (results.length) ? results : null;
+            },
+
+            /**
+             * Removes all listeners registered by pe.event.  Called 
+             * automatically during the unload event.
+             * @method _unload
+             * @static
+             * @private
+             */
+            _unload: function(e) {
+
+                var EU = YAHOO.util.Event, i, j, l, len, index;
+
+                for (i=0,len=unloadListeners.length; i<len; ++i) {
+                    l = unloadListeners[i];
+                    if (l) {
+                        var scope = window;
+                        if (l[EU.ADJ_SCOPE]) {
+                            if (l[EU.ADJ_SCOPE] === true) {
+                                scope = l[EU.OBJ];
+                            } else {
+                                scope = l[EU.ADJ_SCOPE];
+                            }
+                        }
+                        l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ] );
+                        unloadListeners[i] = null;
+                        l=null;
+                        scope=null;
+                    }
+                }
+
+                unloadListeners = null;
+
+                if (listeners && listeners.length > 0) {
+                    j = listeners.length;
+                    while (j) {
+                        index = j-1;
+                        l = listeners[index];
+                        if (l) {
+                            EU.removeListener(l[EU.EL], l[EU.TYPE], 
+                                    l[EU.FN], index);
+                        } 
+                        j = j - 1;
+                    }
+                    l=null;
+
+                    EU.clearCache();
+                }
+
+                for (i=0,len=legacyEvents.length; i<len; ++i) {
+                    // dereference the element
+                    //delete legacyEvents[i][0];
+                    legacyEvents[i][0] = null;
+
+                    // delete the array item
+                    //delete legacyEvents[i];
+                    legacyEvents[i] = null;
+                }
+
+                legacyEvents = null;
+
+                EU._simpleRemove(window, "unload", EU._unload);
+
+            },
+
+            /**
+             * Returns scrollLeft
+             * @method _getScrollLeft
+             * @static
+             * @private
+             */
+            _getScrollLeft: function() {
+                return this._getScroll()[1];
+            },
+
+            /**
+             * Returns scrollTop
+             * @method _getScrollTop
+             * @static
+             * @private
+             */
+            _getScrollTop: function() {
+                return this._getScroll()[0];
+            },
+
+            /**
+             * Returns the scrollTop and scrollLeft.  Used to calculate the 
+             * pageX and pageY in Internet Explorer
+             * @method _getScroll
+             * @static
+             * @private
+             */
+            _getScroll: function() {
+                var dd = document.documentElement, db = document.body;
+                if (dd && (dd.scrollTop || dd.scrollLeft)) {
+                    return [dd.scrollTop, dd.scrollLeft];
+                } else if (db) {
+                    return [db.scrollTop, db.scrollLeft];
+                } else {
+                    return [0, 0];
+                }
+            },
+            
+            /**
+             * Used by old versions of CustomEvent, restored for backwards
+             * compatibility
+             * @method regCE
+             * @private
+             */
+            regCE: function() {
+                // does nothing
+            },
+
+            /**
+             * Adds a DOM event directly without the caching, cleanup, scope adj, etc
+             *
+             * @method _simpleAdd
+             * @param {HTMLElement} el      the element to bind the handler to
+             * @param {string}      sType   the type of event handler
+             * @param {function}    fn      the callback to invoke
+             * @param {boolen}      capture capture or bubble phase
+             * @static
+             * @private
+             */
+            _simpleAdd: function () {
+                if (window.addEventListener) {
+                    return function(el, sType, fn, capture) {
+                        el.addEventListener(sType, fn, (capture));
+                    };
+                } else if (window.attachEvent) {
+                    return function(el, sType, fn, capture) {
+                        el.attachEvent("on" + sType, fn);
+                    };
+                } else {
+                    return function(){};
+                }
+            }(),
+
+            /**
+             * Basic remove listener
+             *
+             * @method _simpleRemove
+             * @param {HTMLElement} el      the element to bind the handler to
+             * @param {string}      sType   the type of event handler
+             * @param {function}    fn      the callback to invoke
+             * @param {boolen}      capture capture or bubble phase
+             * @static
+             * @private
+             */
+            _simpleRemove: function() {
+                if (window.removeEventListener) {
+                    return function (el, sType, fn, capture) {
+                        el.removeEventListener(sType, fn, (capture));
+                    };
+                } else if (window.detachEvent) {
+                    return function (el, sType, fn) {
+                        el.detachEvent("on" + sType, fn);
+                    };
+                } else {
+                    return function(){};
+                }
+            }()
+        };
+
+    }();
+
+    (function() {
+        var EU = YAHOO.util.Event;
+
+        /**
+         * YAHOO.util.Event.on is an alias for addListener
+         * @method on
+         * @see addListener
+         * @static
+         */
+        EU.on = EU.addListener;
+
+        /////////////////////////////////////////////////////////////
+        // DOMReady
+        // based on work by: Dean Edwards/John Resig/Matthias Miller 
+
+        // Internet Explorer: use the readyState of a defered script.
+        // This isolates what appears to be a safe moment to manipulate
+        // the DOM prior to when the document's readyState suggests
+        // it is safe to do so.
+        if (EU.isIE) {
+	
+            document.write(
+'<scr' + 'ipt id="_yui_eu_dr" defer="true" src="//:"></script>');
+        
+            var el = document.getElementById("_yui_eu_dr");
+            el.onreadystatechange = function() {
+                if ("complete" == this.readyState) {
+                    this.parentNode.removeChild(this);
+                    YAHOO.util.Event._ready();
+                }
+            };
+
+            el=null;
+
+            // Process onAvailable/onContentReady items when when the 
+            // DOM is ready.
+            YAHOO.util.Event.onDOMReady(
+                    YAHOO.util.Event._tryPreloadAttach,
+                    YAHOO.util.Event, true);
+        
+        // Safari: The document's readyState in Safari currently will
+        // change to loaded/complete before images are loaded.
+        } else if (EU.webkit) {
+
+            EU._drwatch = setInterval(function(){
+                var rs=document.readyState;
+                if ("loaded" == rs || "complete" == rs) {
+                    clearInterval(EU._drwatch);
+                    EU._drwatch = null;
+                    EU._ready();
+                }
+            }, EU.POLL_INTERVAL); 
+
+        // FireFox and Opera: These browsers provide a event for this
+        // moment.
+        } else {
+
+            EU._simpleAdd(document, "DOMContentLoaded", EU._ready);
+
+        }
+        /////////////////////////////////////////////////////////////
+
+        EU._simpleAdd(window, "load", EU._load);
+        EU._simpleAdd(window, "unload", EU._unload);
+        EU._tryPreloadAttach();
+    })();
+}
+/**
+ * EventProvider is designed to be used with YAHOO.augment to wrap 
+ * CustomEvents in an interface that allows events to be subscribed to 
+ * and fired by name.  This makes it possible for implementing code to
+ * subscribe to an event that either has not been created yet, or will
+ * not be created at all.
+ *
+ * @Class EventProvider
+ */
+YAHOO.util.EventProvider = function() { };
+
+YAHOO.util.EventProvider.prototype = {
+
+    /**
+     * Private storage of custom events
+     * @property __yui_events
+     * @type Object[]
+     * @private
+     */
+    __yui_events: null,
+
+    /**
+     * Private storage of custom event subscribers
+     * @property __yui_subscribers
+     * @type Object[]
+     * @private
+     */
+    __yui_subscribers: null,
+    
+    /**
+     * Subscribe to a CustomEvent by event type
+     *
+     * @method subscribe
+     * @param p_type     {string}   the type, or name of the event
+     * @param p_fn       {function} the function to exectute when the event fires
+     * @param p_obj
+     * @param p_obj      {Object}   An object to be passed along when the event 
+     *                              fires
+     * @param p_override {boolean}  If true, the obj passed in becomes the 
+     *                              execution scope of the listener
+     */
+    subscribe: function(p_type, p_fn, p_obj, p_override) {
+
+        this.__yui_events = this.__yui_events || {};
+        var ce = this.__yui_events[p_type];
+
+        if (ce) {
+            ce.subscribe(p_fn, p_obj, p_override);
+        } else {
+            this.__yui_subscribers = this.__yui_subscribers || {};
+            var subs = this.__yui_subscribers;
+            if (!subs[p_type]) {
+                subs[p_type] = [];
+            }
+            subs[p_type].push(
+                { fn: p_fn, obj: p_obj, override: p_override } );
+        }
+    },
+
+    /**
+     * Unsubscribes one or more listeners the from the specified event
+     * @method unsubscribe
+     * @param p_type {string}   The type, or name of the event
+     * @param p_fn   {Function} The subscribed function to unsubscribe, if not
+     *                          supplied, all subscribers will be removed.
+     * @param p_obj  {Object}   The custom object passed to subscribe.  This is
+     *                        optional, but if supplied will be used to
+     *                        disambiguate multiple listeners that are the same
+     *                        (e.g., you subscribe many object using a function
+     *                        that lives on the prototype)
+     * @return {boolean} true if the subscriber was found and detached.
+     */
+    unsubscribe: function(p_type, p_fn, p_obj) {
+        this.__yui_events = this.__yui_events || {};
+        var ce = this.__yui_events[p_type];
+        if (ce) {
+            return ce.unsubscribe(p_fn, p_obj);
+        } else {
+            return false;
+        }
+    },
+    
+    /**
+     * Removes all listeners from the specified event
+     * @method unsubscribeAll
+     * @param p_type {string}   The type, or name of the event
+     */
+    unsubscribeAll: function(p_type) {
+        return this.unsubscribe(p_type);
+    },
+
+    /**
+     * Creates a new custom event of the specified type.  If a custom event
+     * by that name already exists, it will not be re-created.  In either
+     * case the custom event is returned. 
+     *
+     * @method createEvent
+     *
+     * @param p_type {string} the type, or name of the event
+     * @param p_config {object} optional config params.  Valid properties are:
+     *
+     *  <ul>
+     *    <li>
+     *      scope: defines the default execution scope.  If not defined
+     *      the default scope will be this instance.
+     *    </li>
+     *    <li>
+     *      silent: if true, the custom event will not generate log messages.
+     *      This is false by default.
+     *    </li>
+     *    <li>
+     *      onSubscribeCallback: specifies a callback to execute when the
+     *      event has a new subscriber.  This will fire immediately for
+     *      each queued subscriber if any exist prior to the creation of
+     *      the event.
+     *    </li>
+     *  </ul>
+     *
+     *  @return {CustomEvent} the custom event
+     *
+     */
+    createEvent: function(p_type, p_config) {
+
+        this.__yui_events = this.__yui_events || {};
+        var opts = p_config || {};
+        var events = this.__yui_events;
+
+        if (events[p_type]) {
+        } else {
+
+            var scope  = opts.scope  || this;
+            var silent = opts.silent || null;
+
+            var ce = new YAHOO.util.CustomEvent(p_type, scope, silent,
+                    YAHOO.util.CustomEvent.FLAT);
+            events[p_type] = ce;
+
+            if (opts.onSubscribeCallback) {
+                ce.subscribeEvent.subscribe(opts.onSubscribeCallback);
+            }
+
+            this.__yui_subscribers = this.__yui_subscribers || {};
+            var qs = this.__yui_subscribers[p_type];
+
+            if (qs) {
+                for (var i=0; i<qs.length; ++i) {
+                    ce.subscribe(qs[i].fn, qs[i].obj, qs[i].override);
+                }
+            }
+        }
+
+        return events[p_type];
+    },
+
+
+   /**
+     * Fire a custom event by name.  The callback functions will be executed
+     * from the scope specified when the event was created, and with the 
+     * following parameters:
+     *   <ul>
+     *   <li>The first argument fire() was executed with</li>
+     *   <li>The custom object (if any) that was passed into the subscribe() 
+     *       method</li>
+     *   </ul>
+     * @method fireEvent
+     * @param p_type    {string}  the type, or name of the event
+     * @param arguments {Object*} an arbitrary set of parameters to pass to 
+     *                            the handler.
+     * @return {boolean} the return value from CustomEvent.fire, or null if 
+     *                   the custom event does not exist.
+     */
+    fireEvent: function(p_type, arg1, arg2, etc) {
+
+        this.__yui_events = this.__yui_events || {};
+        var ce = this.__yui_events[p_type];
+
+        if (ce) {
+            var args = [];
+            for (var i=1; i<arguments.length; ++i) {
+                args.push(arguments[i]);
+            }
+            return ce.fire.apply(ce, args);
+        } else {
+            return null;
+        }
+    },
+
+    /**
+     * Returns true if the custom event of the provided type has been created
+     * with createEvent.
+     * @method hasEvent
+     * @param type {string} the type, or name of the event
+     */
+    hasEvent: function(type) {
+        if (this.__yui_events) {
+            if (this.__yui_events[type]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+};
+
+/**
+* KeyListener is a utility that provides an easy interface for listening for
+* keydown/keyup events fired against DOM elements.
+* @namespace YAHOO.util
+* @class KeyListener
+* @constructor
+* @param {HTMLElement} attachTo The element or element ID to which the key 
+*                               event should be attached
+* @param {String}      attachTo The element or element ID to which the key
+*                               event should be attached
+* @param {Object}      keyData  The object literal representing the key(s) 
+*                               to detect. Possible attributes are 
+*                               shift(boolean), alt(boolean), ctrl(boolean) 
+*                               and keys(either an int or an array of ints 
+*                               representing keycodes).
+* @param {Function}    handler  The CustomEvent handler to fire when the 
+*                               key event is detected
+* @param {Object}      handler  An object literal representing the handler. 
+* @param {String}      event    Optional. The event (keydown or keyup) to 
+*                               listen for. Defaults automatically to keydown.
+*/
+YAHOO.util.KeyListener = function(attachTo, keyData, handler, event) {
+    if (!attachTo) {
+    } else if (!keyData) {
+    } else if (!handler) {
+    } 
+    
+    if (!event) {
+        event = YAHOO.util.KeyListener.KEYDOWN;
+    }
+
+    /**
+    * The CustomEvent fired internally when a key is pressed
+    * @event keyEvent
+    * @private
+    * @param {Object} keyData The object literal representing the key(s) to 
+    *                         detect. Possible attributes are shift(boolean), 
+    *                         alt(boolean), ctrl(boolean) and keys(either an 
+    *                         int or an array of ints representing keycodes).
+    */
+    var keyEvent = new YAHOO.util.CustomEvent("keyPressed");
+    
+    /**
+    * The CustomEvent fired when the KeyListener is enabled via the enable() 
+    * function
+    * @event enabledEvent
+    * @param {Object} keyData The object literal representing the key(s) to 
+    *                         detect. Possible attributes are shift(boolean), 
+    *                         alt(boolean), ctrl(boolean) and keys(either an 
+    *                         int or an array of ints representing keycodes).
+    */
+    this.enabledEvent = new YAHOO.util.CustomEvent("enabled");
+
+    /**
+    * The CustomEvent fired when the KeyListener is disabled via the 
+    * disable() function
+    * @event disabledEvent
+    * @param {Object} keyData The object literal representing the key(s) to 
+    *                         detect. Possible attributes are shift(boolean), 
+    *                         alt(boolean), ctrl(boolean) and keys(either an 
+    *                         int or an array of ints representing keycodes).
+    */
+    this.disabledEvent = new YAHOO.util.CustomEvent("disabled");
+
+    if (typeof attachTo == 'string') {
+        attachTo = document.getElementById(attachTo);
+    }
+
+    if (typeof handler == 'function') {
+        keyEvent.subscribe(handler);
+    } else {
+        keyEvent.subscribe(handler.fn, handler.scope, handler.correctScope);
+    }
+
+    /**
+    * Handles the key event when a key is pressed.
+    * @method handleKeyPress
+    * @param {DOMEvent} e   The keypress DOM event
+    * @param {Object}   obj The DOM event scope object
+    * @private
+    */
+    function handleKeyPress(e, obj) {
+        if (! keyData.shift) {  
+            keyData.shift = false; 
+        }
+        if (! keyData.alt) {    
+            keyData.alt = false;
+        }
+        if (! keyData.ctrl) {
+            keyData.ctrl = false;
+        }
+
+        // check held down modifying keys first
+        if (e.shiftKey == keyData.shift && 
+            e.altKey   == keyData.alt &&
+            e.ctrlKey  == keyData.ctrl) { // if we pass this, all modifiers match
+            
+            var dataItem;
+            var keyPressed;
+
+            if (keyData.keys instanceof Array) {
+                for (var i=0;i<keyData.keys.length;i++) {
+                    dataItem = keyData.keys[i];
+
+                    if (dataItem == e.charCode ) {
+                        keyEvent.fire(e.charCode, e);
+                        break;
+                    } else if (dataItem == e.keyCode) {
+                        keyEvent.fire(e.keyCode, e);
+                        break;
+                    }
+                }
+            } else {
+                dataItem = keyData.keys;
+                if (dataItem == e.charCode ) {
+                    keyEvent.fire(e.charCode, e);
+                } else if (dataItem == e.keyCode) {
+                    keyEvent.fire(e.keyCode, e);
+                }
+            }
+        }
+    }
+
+    /**
+    * Enables the KeyListener by attaching the DOM event listeners to the 
+    * target DOM element
+    * @method enable
+    */
+    this.enable = function() {
+        if (! this.enabled) {
+            YAHOO.util.Event.addListener(attachTo, event, handleKeyPress);
+            this.enabledEvent.fire(keyData);
+        }
+        /**
+        * Boolean indicating the enabled/disabled state of the Tooltip
+        * @property enabled
+        * @type Boolean
+        */
+        this.enabled = true;
+    };
+
+    /**
+    * Disables the KeyListener by removing the DOM event listeners from the 
+    * target DOM element
+    * @method disable
+    */
+    this.disable = function() {
+        if (this.enabled) {
+            YAHOO.util.Event.removeListener(attachTo, event, handleKeyPress);
+            this.disabledEvent.fire(keyData);
+        }
+        this.enabled = false;
+    };
+
+    /**
+    * Returns a String representation of the object.
+    * @method toString
+    * @return {String}  The string representation of the KeyListener
+    */ 
+    this.toString = function() {
+        return "KeyListener [" + keyData.keys + "] " + attachTo.tagName + 
+                (attachTo.id ? "[" + attachTo.id + "]" : "");
+    };
+
+};
+
+/**
+* Constant representing the DOM "keydown" event.
+* @property YAHOO.util.KeyListener.KEYDOWN
+* @static
+* @final
+* @type String
+*/
+YAHOO.util.KeyListener.KEYDOWN = "keydown";
+
+/**
+* Constant representing the DOM "keyup" event.
+* @property YAHOO.util.KeyListener.KEYUP
+* @static
+* @final
+* @type String
+*/
+YAHOO.util.KeyListener.KEYUP = "keyup";
+YAHOO.register("event", YAHOO.util.Event, {version: "2.2.1", build: "193"});

Added: jifty/branches/virtual-models/share/web/static/js/yui/menu.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/share/web/static/js/yui/menu.js	Mon May  7 16:28:32 2007
@@ -0,0 +1,8675 @@
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+
+
+/**
+* @module menu
+* @description <p>The Menu family of components features a collection of 
+* controls that make it easy to add menus to your website or web application.  
+* With the Menu Controls you can create website fly-out menus, customized 
+* context menus, or application-style menu bars with just a small amount of 
+* scripting.</p><p>The Menu family of controls features:</p>
+* <ul>
+*    <li>Screen-reader accessibility.</li>
+*    <li>Keyboard and mouse navigation.</li>
+*    <li>A rich event model that provides access to all of a menu's 
+*    interesting moments.</li>
+*    <li>Support for 
+*    <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive
+*    Enhancement</a>; Menus can be created from simple, 
+*    semantic markup on the page or purely through JavaScript.</li>
+* </ul>
+* @title Menu
+* @namespace YAHOO.widget
+* @requires Event, Dom, Container
+*/
+(function() {
+
+var Dom = YAHOO.util.Dom,
+    Event = YAHOO.util.Event;
+
+
+/**
+* Singleton that manages a collection of all menus and menu items.  Listens for 
+* DOM events at the document level and dispatches the events to the 
+* corresponding menu or menu item.
+*
+* @namespace YAHOO.widget
+* @class MenuManager
+* @static
+*/
+YAHOO.widget.MenuManager = function() {
+
+    // Private member variables
+
+
+    // Flag indicating if the DOM event handlers have been attached
+
+    var m_bInitializedEventHandlers = false,
+
+
+        // Collection of menus
+
+        m_oMenus = {},
+    
+    
+        //  Collection of menu items 
+
+        m_oItems = {},
+
+
+        // Collection of visible menus
+    
+        m_oVisibleMenus = {},
+
+
+        // Map of DOM event types to their equivalent CustomEvent types
+    
+        m_oEventTypes =  {
+            "click": "clickEvent",
+            "mousedown": "mouseDownEvent",
+            "mouseup": "mouseUpEvent",
+            "mouseover": "mouseOverEvent",
+            "mouseout": "mouseOutEvent",
+            "keydown": "keyDownEvent",
+            "keyup": "keyUpEvent",
+            "keypress": "keyPressEvent"
+        },
+
+
+        m_oFocusedMenuItem = null;
+
+
+
+
+    // Private methods
+
+
+    /**
+    * @method addItem
+    * @description Adds an item to the collection of known menu items.
+    * @private
+    * @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem 
+    * instance to be added.
+    */
+    function addItem(p_oItem) {
+
+        var sId = p_oItem.id;
+
+        if(p_oItem && m_oItems[sId] != p_oItem) {
+    
+            m_oItems[sId] = p_oItem;
+
+            p_oItem.destroyEvent.subscribe(onItemDestroy);
+
+
+        }
+    
+    }
+
+
+    /**
+    * @method removeItem
+    * @description Removes an item from the collection of known menu items.
+    * @private
+    * @param {YAHOO.widget.MenuItem} p_oItem Object specifying the MenuItem 
+    * instance to be removed.
+    */
+    function removeItem(p_oItem) {
+    
+        var sId = p_oItem.id;
+
+        if(sId && m_oItems[sId]) {
+
+            delete m_oItems[sId];
+
+
+        }
+    
+    }
+
+
+    /**
+    * @method getMenuRootElement
+    * @description Finds the root DIV node of a menu or the root LI node of a 
+    * menu item.
+    * @private
+    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object specifying 
+    * an HTML element.
+    */
+    function getMenuRootElement(p_oElement) {
+    
+        var oParentNode;
+
+        if(p_oElement && p_oElement.tagName) {
+        
+            switch(p_oElement.tagName.toUpperCase()) {
+                    
+                case "DIV":
+    
+                    oParentNode = p_oElement.parentNode;
+    
+                    // Check if the DIV is the inner "body" node of a menu
+
+                    if(
+                        (
+                            Dom.hasClass(p_oElement, "hd") ||
+                            Dom.hasClass(p_oElement, "bd") ||
+                            Dom.hasClass(p_oElement, "ft")
+                        )
+                        && 
+                        oParentNode && 
+                        oParentNode.tagName && 
+                        oParentNode.tagName.toUpperCase() == "DIV"
+                    ) {
+                    
+                        return oParentNode;
+                    
+                    }
+                    else {
+                    
+                        return p_oElement;
+                    
+                    }
+                
+                break;
+
+                case "LI":
+    
+                    return p_oElement;
+
+                default:
+    
+                    oParentNode = p_oElement.parentNode;
+    
+                    if(oParentNode) {
+                    
+                        return getMenuRootElement(oParentNode);
+                    
+                    }
+                
+                break;
+            
+            }
+
+        }
+        
+    }
+
+
+
+    // Private event handlers
+
+
+    /**
+    * @method onDOMEvent
+    * @description Generic, global event handler for all of a menu's DOM-based 
+    * events.  This listens for events against the document object.  If the 
+    * target of a given event is a member of a menu or menu item's DOM, the 
+    * instance's corresponding Custom Event is fired.
+    * @private
+    * @param {Event} p_oEvent Object representing the DOM event object passed 
+    * back by the event utility (YAHOO.util.Event).
+    */
+    function onDOMEvent(p_oEvent) {
+
+        // Get the target node of the DOM event
+    
+        var oTarget = Event.getTarget(p_oEvent),
+
+
+        // See if the target of the event was a menu, or a menu item
+
+            oElement = getMenuRootElement(oTarget),
+            oMenuItem,
+            oMenu; 
+
+
+        if(oElement) {
+
+            var sTagName = oElement.tagName.toUpperCase();
+    
+            if(sTagName == "LI") {
+        
+                var sId = oElement.id;
+        
+                if(sId && m_oItems[sId]) {
+        
+                    oMenuItem = m_oItems[sId];
+                    oMenu = oMenuItem.parent;
+        
+                }
+            
+            }
+            else if(sTagName == "DIV") {
+            
+                if(oElement.id) {
+                
+                    oMenu = m_oMenus[oElement.id];
+                
+                }
+            
+            }
+
+        }
+
+
+        if(oMenu) {
+
+            var sCustomEventType = m_oEventTypes[p_oEvent.type];
+
+
+            // Fire the Custom Event that corresponds the current DOM event    
+    
+            if(oMenuItem && !oMenuItem.cfg.getProperty("disabled")) {
+
+                oMenuItem[sCustomEventType].fire(p_oEvent);                   
+
+
+                if (p_oEvent.type == "keyup" || p_oEvent.type == "mousedown") {
+
+                    if (m_oFocusedMenuItem != oMenuItem) {
+                    
+                        if(m_oFocusedMenuItem) {
+
+                            m_oFocusedMenuItem.blurEvent.fire();
+                        
+                        }
+
+                        oMenuItem.focusEvent.fire();
+                    
+                    }
+                
+                }
+
+            }
+    
+            oMenu[sCustomEventType].fire(p_oEvent, oMenuItem);
+        
+        }
+        else if(p_oEvent.type == "mousedown") {
+
+            if(m_oFocusedMenuItem) {
+
+                m_oFocusedMenuItem.blurEvent.fire();
+
+                m_oFocusedMenuItem = null;
+
+            }
+
+
+            /*
+                If the target of the event wasn't a menu, hide all 
+                dynamically positioned menus
+            */
+            
+            for(var i in m_oMenus) {
+    
+                if(YAHOO.lang.hasOwnProperty(m_oMenus,i)) {
+    
+                    oMenu = m_oMenus[i];
+    
+                    if(
+                        oMenu.cfg.getProperty("clicktohide") && 
+                        oMenu.cfg.getProperty("position") == "dynamic"
+                    ) {
+    
+                        oMenu.hide();
+    
+                    }
+                    else {
+
+                        oMenu.clearActiveItem(true);
+    
+                    }
+    
+                }
+    
+            } 
+
+        }
+        else if(p_oEvent.type == "keyup") { 
+
+            if(m_oFocusedMenuItem) {
+
+                m_oFocusedMenuItem.blurEvent.fire();
+
+                m_oFocusedMenuItem = null;
+
+            }
+
+        }
+
+    }
+
+
+    /**
+    * @method onMenuDestroy
+    * @description "destroy" event handler for a menu.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onMenuDestroy(p_sType, p_aArgs) {
+
+        if(m_oMenus[this.id]) {
+
+            delete m_oMenus[this.id];
+
+
+        }
+
+    }
+
+
+    /**
+    * @method onMenuFocus
+    * @description "focus" event handler for a MenuItem instance.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onMenuFocus(p_sType, p_aArgs) {
+
+        var oItem = p_aArgs[0];
+        
+        if (oItem) {
+
+            m_oFocusedMenuItem = oItem;
+        
+        }
+
+    }
+
+
+    /**
+    * @method onMenuBlur
+    * @description "blur" event handler for a MenuItem instance.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onMenuBlur(p_sType, p_aArgs) {
+
+        m_oFocusedMenuItem = null;
+
+    }
+
+
+    /**
+    * @method onItemDestroy
+    * @description "destroy" event handler for a MenuItem instance.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onItemDestroy(p_sType, p_aArgs) {
+
+        var sId = this.id;
+
+        if(sId && m_oItems[sId]) {
+
+            delete m_oItems[sId];
+
+        }
+
+    }
+
+
+    /**
+    * @method onMenuVisibleConfigChange
+    * @description Event handler for when the "visible" configuration property 
+    * of a Menu instance changes.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onMenuVisibleConfigChange(p_sType, p_aArgs) {
+
+        var bVisible = p_aArgs[0];
+        
+        if(bVisible) {
+
+            m_oVisibleMenus[this.id] = this;
+            
+        
+        }
+        else if(m_oVisibleMenus[this.id]) {
+        
+            delete m_oVisibleMenus[this.id];
+            
+        
+        }
+    
+    }
+
+
+    /**
+    * @method onItemAdded
+    * @description "itemadded" event handler for a Menu instance.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onItemAdded(p_sType, p_aArgs) {
+    
+        addItem(p_aArgs[0]);
+    
+    }
+    
+
+    /**
+    * @method onItemRemoved
+    * @description "itemremoved" event handler for a Menu instance.
+    * @private
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    */
+    function onItemRemoved(p_sType, p_aArgs) {
+
+        removeItem(p_aArgs[0]);
+    
+    }
+
+
+
+    return {
+
+        // Privileged methods
+
+
+        /**
+        * @method addMenu
+        * @description Adds a menu to the collection of known menus.
+        * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu  
+        * instance to be added.
+        */
+        addMenu: function(p_oMenu) {
+    
+            if(p_oMenu && p_oMenu.id && !m_oMenus[p_oMenu.id]) {
+    
+                m_oMenus[p_oMenu.id] = p_oMenu;
+            
+        
+                if(!m_bInitializedEventHandlers) {
+        
+                    var oDoc = document;
+            
+                    Event.on(oDoc, "mouseover", onDOMEvent, this, true);
+                    Event.on(oDoc, "mouseout", onDOMEvent, this, true);
+                    Event.on(oDoc, "mousedown", onDOMEvent, this, true);
+                    Event.on(oDoc, "mouseup", onDOMEvent, this, true);
+                    Event.on(oDoc, "click", onDOMEvent, this, true);
+                    Event.on(oDoc, "keydown", onDOMEvent, this, true);
+                    Event.on(oDoc, "keyup", onDOMEvent, this, true);
+                    Event.on(oDoc, "keypress", onDOMEvent, this, true);
+
+
+                    m_bInitializedEventHandlers = true;
+                    
+        
+                }
+        
+                p_oMenu.destroyEvent.subscribe(onMenuDestroy);
+                
+                p_oMenu.cfg.subscribeToConfigEvent(
+                    "visible", 
+                    onMenuVisibleConfigChange
+                );
+        
+                p_oMenu.itemAddedEvent.subscribe(onItemAdded);
+                p_oMenu.itemRemovedEvent.subscribe(onItemRemoved);
+                p_oMenu.focusEvent.subscribe(onMenuFocus);
+                p_oMenu.blurEvent.subscribe(onMenuBlur);
+    
+    
+            }
+    
+        },
+
+    
+        /**
+        * @method removeMenu
+        * @description Removes a menu from the collection of known menus.
+        * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu  
+        * instance to be removed.
+        */
+        removeMenu: function(p_oMenu) {
+    
+            if(p_oMenu && m_oMenus[p_oMenu.id]) {
+    
+                delete m_oMenus[p_oMenu.id];
+    
+    
+            }
+    
+        },
+    
+    
+        /**
+        * @method hideVisible
+        * @description Hides all visible, dynamically positioned menus.
+        */
+        hideVisible: function() {
+    
+            var oMenu;
+    
+            for(var i in m_oVisibleMenus) {
+    
+                if(YAHOO.lang.hasOwnProperty(m_oVisibleMenus,i)) {
+    
+                    oMenu = m_oVisibleMenus[i];
+    
+                    if(oMenu.cfg.getProperty("position") == "dynamic") {
+    
+                        oMenu.hide();
+    
+                    }
+    
+                }
+    
+            }        
+        
+        },
+
+
+        /**
+        * @method getMenus
+        * @description Returns an array of all menus registered with the 
+        * menu manger.
+        * @return {Array}
+        */
+        getMenus: function() {
+        
+            return m_oMenus;
+        
+        },
+
+
+        /**
+        * @method getMenu
+        * @description Returns a menu with the specified id.
+        * @param {String} p_sId String specifying the id of the menu to
+        * be retrieved.
+        * @return {YAHOO.widget.Menu}
+        */
+        getMenu: function(p_sId) {
+    
+            if(m_oMenus[p_sId]) {
+            
+                return m_oMenus[p_sId];
+            
+            }
+        
+        },
+
+
+        /**
+        * @method getFocusedMenuItem
+        * @description Returns a reference to the menu item that currently 
+        * has focus.
+        * @return {YAHOO.widget.MenuItem}
+        */
+        getFocusedMenuItem: function() {
+
+            return m_oFocusedMenuItem;
+
+        },
+
+
+        /**
+        * @method getFocusedMenu
+        * @description Returns a reference to the menu that currently has focus.
+        * @return {YAHOO.widget.Menu}
+        */
+        getFocusedMenu: function() {
+
+            if(m_oFocusedMenuItem) {
+
+                return (m_oFocusedMenuItem.parent.getRoot());
+            
+            }
+
+        },
+
+    
+        /**
+        * @method toString
+        * @description Returns a string representing the menu manager.
+        * @return {String}
+        */
+        toString: function() {
+        
+            return ("MenuManager");
+        
+        }
+
+    };
+
+}();
+
+})();
+
+
+
+/**
+* The Menu class creates a container that holds a vertical list representing 
+* a set of options or commands.  Menu is the base class for all 
+* menu containers. 
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;div&#62;</code> element of the menu.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;select&#62;</code> element to be used as the data source 
+* for the menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object 
+* specifying the <code>&#60;div&#62;</code> element of the menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement 
+* Object specifying the <code>&#60;select&#62;</code> element to be used as 
+* the data source for the menu.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu. See configuration class documentation for 
+* more details.
+* @namespace YAHOO.widget
+* @class Menu
+* @constructor
+* @extends YAHOO.widget.Overlay
+*/
+(function() {
+
+var Dom = YAHOO.util.Dom,
+    Event = YAHOO.util.Event,
+    CustomEvent = YAHOO.util.CustomEvent,
+    Lang = YAHOO.lang;
+
+
+YAHOO.widget.Menu = function(p_oElement, p_oConfig) {
+
+    if(p_oConfig) {
+
+        this.parent = p_oConfig.parent;
+        this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload;
+        this.itemData = p_oConfig.itemData || p_oConfig.itemdata;
+
+    }
+
+
+    YAHOO.widget.Menu.superclass.constructor.call(
+        this, 
+        p_oElement, 
+        p_oConfig
+    );
+
+};
+
+
+/**
+* Constant representing the name of the Menu's events
+* @property YAHOO.widget.Menu._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Menu._EVENT_TYPES = {
+
+    "MOUSE_OVER": "mouseover",
+    "MOUSE_OUT": "mouseout",
+    "MOUSE_DOWN": "mousedown",
+    "MOUSE_UP": "mouseup",
+    "CLICK": "click",
+    "KEY_PRESS": "keypress",
+    "KEY_DOWN": "keydown",
+    "KEY_UP": "keyup",
+    "FOCUS": "focus",
+    "BLUR": "blur",
+    "ITEM_ADDED": "itemAdded",
+    "ITEM_REMOVED": "itemRemoved"
+
+};
+
+
+
+/**
+* @method _checkPosition
+* @description Checks to make sure that the value of the "position" property 
+* is one of the supported strings. Returns true if the position is supported.
+* @private
+* @param {Object} p_sPosition String specifying the position of the menu.
+* @return {Boolean}
+*/
+YAHOO.widget.Menu._checkPosition = function(p_sPosition) {
+
+    if(typeof p_sPosition == "string") {
+
+        var sPosition = p_sPosition.toLowerCase();
+
+        return ("dynamic,static".indexOf(sPosition) != -1);
+
+    }
+
+};
+
+
+
+/**
+* Constant representing the Menu's configuration properties
+* @property YAHOO.widget.Menu._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.Menu._DEFAULT_CONFIG = {
+
+    "VISIBLE": { 
+        key: "visible", 
+        value: false, 
+        validator: Lang.isBoolean
+    }, 
+
+    "CONSTRAIN_TO_VIEWPORT": {
+        key: "constraintoviewport", 
+        value: true, 
+        validator: Lang.isBoolean, 
+        supercedes: ["iframe","x","y","xy"]
+    }, 
+
+    "POSITION": { 
+        key: "position", 
+        value: "dynamic", 
+        validator: YAHOO.widget.Menu._checkPosition, 
+        supercedes: ["visible"] 
+    }, 
+
+    "SUBMENU_ALIGNMENT": { 
+        key: "submenualignment", 
+        value: ["tl","tr"]
+    },
+
+    "AUTO_SUBMENU_DISPLAY": { 
+        key: "autosubmenudisplay", 
+        value: true, 
+        validator: Lang.isBoolean 
+    }, 
+
+    "SHOW_DELAY": { 
+        key: "showdelay", 
+        value: 250, 
+        validator: Lang.isNumber 
+    }, 
+
+    "HIDE_DELAY": { 
+        key: "hidedelay", 
+        value: 0, 
+        validator: Lang.isNumber, 
+        suppressEvent: true
+    }, 
+
+    "SUBMENU_HIDE_DELAY": { 
+        key: "submenuhidedelay", 
+        value: 250, 
+        validator: Lang.isNumber
+    }, 
+
+    "CLICK_TO_HIDE": { 
+        key: "clicktohide", 
+        value: true, 
+        validator: Lang.isBoolean
+    },
+
+    "CONTAINER": { 
+        key: "container"
+    }, 
+
+    "MAX_HEIGHT": { 
+        key: "maxheight", 
+        value: 0, 
+        validator: Lang.isNumber
+    }, 
+
+    "CLASS_NAME": { 
+        key: "classname", 
+        value: null, 
+        validator: Lang.isString
+    }
+
+};
+
+
+YAHOO.lang.extend(YAHOO.widget.Menu, YAHOO.widget.Overlay, {
+
+
+// Constants
+
+
+/**
+* @property CSS_CLASS_NAME
+* @description String representing the CSS class(es) to be applied to the 
+* menu's <code>&#60;div&#62;</code> element.
+* @default "yuimenu"
+* @final
+* @type String
+*/
+CSS_CLASS_NAME: "yuimenu",
+
+
+/**
+* @property ITEM_TYPE
+* @description Object representing the type of menu item to instantiate and 
+* add when parsing the child nodes (either <code>&#60;li&#62;</code> element, 
+* <code>&#60;optgroup&#62;</code> element or <code>&#60;option&#62;</code>) 
+* of the menu's source HTML element.
+* @default YAHOO.widget.MenuItem
+* @final
+* @type YAHOO.widget.MenuItem
+*/
+ITEM_TYPE: null,
+
+
+/**
+* @property GROUP_TITLE_TAG_NAME
+* @description String representing the tagname of the HTML element used to 
+* title the menu's item groups.
+* @default H6
+* @final
+* @type String
+*/
+GROUP_TITLE_TAG_NAME: "h6",
+
+
+
+// Private properties
+
+
+/** 
+* @property _nHideDelayId
+* @description Number representing the time-out setting used to cancel the 
+* hiding of a menu.
+* @default null
+* @private
+* @type Number
+*/
+_nHideDelayId: null,
+
+
+/** 
+* @property _nShowDelayId
+* @description Number representing the time-out setting used to cancel the 
+* showing of a menu.
+* @default null
+* @private
+* @type Number
+*/
+_nShowDelayId: null,
+
+
+/** 
+* @property _nSubmenuHideDelayId
+* @description Number representing the time-out setting used to cancel the 
+* hiding of a submenu.
+* @default null
+* @private
+* @type Number
+*/
+_nSubmenuHideDelayId: null,
+
+
+/** 
+* @property _nBodyScrollId
+* @description Number representing the time-out setting used to cancel the 
+* scrolling of the menu's body element.
+* @default null
+* @private
+* @type Number
+*/
+_nBodyScrollId: null,
+
+
+/** 
+* @property _bHideDelayEventHandlersAssigned
+* @description Boolean indicating if the "mouseover" and "mouseout" event 
+* handlers used for hiding the menu via a call to "window.setTimeout" have 
+* already been assigned.
+* @default false
+* @private
+* @type Boolean
+*/
+_bHideDelayEventHandlersAssigned: false,
+
+
+/**
+* @property _bHandledMouseOverEvent
+* @description Boolean indicating the current state of the menu's 
+* "mouseover" event.
+* @default false
+* @private
+* @type Boolean
+*/
+_bHandledMouseOverEvent: false,
+
+
+/**
+* @property _bHandledMouseOutEvent
+* @description Boolean indicating the current state of the menu's
+* "mouseout" event.
+* @default false
+* @private
+* @type Boolean
+*/
+_bHandledMouseOutEvent: false,
+
+
+/**
+* @property _aGroupTitleElements
+* @description Array of HTML element used to title groups of menu items.
+* @default []
+* @private
+* @type Array
+*/
+_aGroupTitleElements: null,
+
+
+/**
+* @property _aItemGroups
+* @description Multi-dimensional Array representing the menu items as they
+* are grouped in the menu.
+* @default []
+* @private
+* @type Array
+*/
+_aItemGroups: null,
+
+
+/**
+* @property _aListElements
+* @description Array of <code>&#60;ul&#62;</code> elements, each of which is 
+* the parent node for each item's <code>&#60;li&#62;</code> element.
+* @default []
+* @private
+* @type Array
+*/
+_aListElements: null,
+
+
+/**
+* @property _nCurrentMouseX
+* @description The current x coordinate of the mouse inside the area of 
+* the menu.
+* @default 0
+* @private
+* @type Number
+*/
+_nCurrentMouseX: 0,
+
+
+/**
+* @property _nMaxHeight
+* @description The original value of the "maxheight" configuration property 
+* as set by the user.
+* @default -1
+* @private
+* @type Number
+*/
+_nMaxHeight: -1,
+
+
+/**
+* @property _bStopMouseEventHandlers
+* @description Stops "mouseover," "mouseout," and "mousemove" event handlers 
+* from executing.
+* @default false
+* @private
+* @type Boolean
+*/
+_bStopMouseEventHandlers: false,
+
+
+/**
+* @property _sClassName
+* @description The current value of the "classname" configuration attribute.
+* @default null
+* @private
+* @type String
+*/
+_sClassName: null,
+
+
+
+// Public properties
+
+
+/**
+* @property lazyLoad
+* @description Boolean indicating if the menu's "lazy load" feature is 
+* enabled.  If set to "true," initialization and rendering of the menu's 
+* items will be deferred until the first time it is made visible.  This 
+* property should be set via the constructor using the configuration 
+* object literal.
+* @default false
+* @type Boolean
+*/
+lazyLoad: false,
+
+
+/**
+* @property itemData
+* @description Array of items to be added to the menu.  The array can contain 
+* strings representing the text for each item to be created, object literals 
+* representing the menu item configuration properties, or MenuItem instances.  
+* This property should be set via the constructor using the configuration 
+* object literal.
+* @default null
+* @type Array
+*/
+itemData: null,
+
+
+/**
+* @property activeItem
+* @description Object reference to the item in the menu that has is selected.
+* @default null
+* @type YAHOO.widget.MenuItem
+*/
+activeItem: null,
+
+
+/**
+* @property parent
+* @description Object reference to the menu's parent menu or menu item.  
+* This property can be set via the constructor using the configuration 
+* object literal.
+* @default null
+* @type YAHOO.widget.MenuItem
+*/
+parent: null,
+
+
+/**
+* @property srcElement
+* @description Object reference to the HTML element (either 
+* <code>&#60;select&#62;</code> or <code>&#60;div&#62;</code>) used to 
+* create the menu.
+* @default null
+* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+* level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a 
+* href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
+* html#ID-22445964">HTMLDivElement</a>
+*/
+srcElement: null,
+
+
+
+// Events
+
+
+/**
+* @event mouseOverEvent
+* @description Fires when the mouse has entered the menu.  Passes back 
+* the DOM Event object as an argument.
+*/
+mouseOverEvent: null,
+
+
+/**
+* @event mouseOutEvent
+* @description Fires when the mouse has left the menu.  Passes back the DOM 
+* Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+mouseOutEvent: null,
+
+
+/**
+* @event mouseDownEvent
+* @description Fires when the user mouses down on the menu.  Passes back the 
+* DOM Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+mouseDownEvent: null,
+
+
+/**
+* @event mouseUpEvent
+* @description Fires when the user releases a mouse button while the mouse is 
+* over the menu.  Passes back the DOM Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+mouseUpEvent: null,
+
+
+/**
+* @event clickEvent
+* @description Fires when the user clicks the on the menu.  Passes back the 
+* DOM Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+clickEvent: null,
+
+
+/**
+* @event keyPressEvent
+* @description Fires when the user presses an alphanumeric key when one of the
+* menu's items has focus.  Passes back the DOM Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+keyPressEvent: null,
+
+
+/**
+* @event keyDownEvent
+* @description Fires when the user presses a key when one of the menu's items 
+* has focus.  Passes back the DOM Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+keyDownEvent: null,
+
+
+/**
+* @event keyUpEvent
+* @description Fires when the user releases a key when one of the menu's items 
+* has focus.  Passes back the DOM Event object as an argument.
+* @type YAHOO.util.CustomEvent
+*/
+keyUpEvent: null,
+
+
+/**
+* @event itemAddedEvent
+* @description Fires when an item is added to the menu.
+* @type YAHOO.util.CustomEvent
+*/
+itemAddedEvent: null,
+
+
+/**
+* @event itemRemovedEvent
+* @description Fires when an item is removed to the menu.
+* @type YAHOO.util.CustomEvent
+*/
+itemRemovedEvent: null,
+
+
+/**
+* @method init
+* @description The Menu class's initialization method. This method is 
+* automatically called by the constructor, and sets up all DOM references 
+* for pre-existing markup, and creates required markup if it is not 
+* already present.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;div&#62;</code> element of the menu.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;select&#62;</code> element to be used as the data source 
+* for the menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+* level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object 
+* specifying the <code>&#60;div&#62;</code> element of the menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+* level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement 
+* Object specifying the <code>&#60;select&#62;</code> element to be used as 
+* the data source for the menu.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu. See configuration class documentation for 
+* more details.
+*/
+init: function(p_oElement, p_oConfig) {
+
+    this._aItemGroups = [];
+    this._aListElements = [];
+    this._aGroupTitleElements = [];
+
+    if(!this.ITEM_TYPE) {
+
+        this.ITEM_TYPE = YAHOO.widget.MenuItem;
+
+    }
+
+
+    var oElement;
+
+    if(typeof p_oElement == "string") {
+
+        oElement = document.getElementById(p_oElement);
+
+    }
+    else if(p_oElement.tagName) {
+
+        oElement = p_oElement;
+
+    }
+
+
+    if(oElement && oElement.tagName) {
+
+        switch(oElement.tagName.toUpperCase()) {
+    
+            case "DIV":
+
+                this.srcElement = oElement;
+
+                if(!oElement.id) {
+
+                    oElement.setAttribute("id", Dom.generateId());
+
+                }
+
+
+                /* 
+                    Note: we don't pass the user config in here yet 
+                    because we only want it executed once, at the lowest 
+                    subclass level.
+                */ 
+            
+                YAHOO.widget.Menu.superclass.init.call(this, oElement);
+
+                this.beforeInitEvent.fire(YAHOO.widget.Menu);
+
+
+    
+            break;
+    
+            case "SELECT":
+    
+                this.srcElement = oElement;
+
+    
+                /*
+                    The source element is not something that we can use 
+                    outright, so we need to create a new Overlay
+
+                    Note: we don't pass the user config in here yet 
+                    because we only want it executed once, at the lowest 
+                    subclass level.
+                */ 
+
+                YAHOO.widget.Menu.superclass.init.call(this, Dom.generateId());
+
+                this.beforeInitEvent.fire(YAHOO.widget.Menu);
+
+
+
+            break;
+
+        }
+
+    }
+    else {
+
+        /* 
+            Note: we don't pass the user config in here yet 
+            because we only want it executed once, at the lowest 
+            subclass level.
+        */ 
+    
+        YAHOO.widget.Menu.superclass.init.call(this, p_oElement);
+
+        this.beforeInitEvent.fire(YAHOO.widget.Menu);
+
+
+
+    }
+
+
+    if(this.element) {
+
+        var oEl = this.element;
+
+        Dom.addClass(oEl, this.CSS_CLASS_NAME);
+
+
+        // Subscribe to Custom Events
+
+        this.initEvent.subscribe(this._onInit, this, true);
+        this.beforeRenderEvent.subscribe(this._onBeforeRender, this, true);
+        this.renderEvent.subscribe(this._onRender);
+        this.beforeShowEvent.subscribe(this._onBeforeShow, this, true);
+        this.showEvent.subscribe(this._onShow, this, true);
+        this.beforeHideEvent.subscribe(this._onBeforeHide, this, true);
+        this.hideEvent.subscribe(this._onHide, this, true);
+        this.mouseOverEvent.subscribe(this._onMouseOver, this, true);
+        this.mouseOutEvent.subscribe(this._onMouseOut, this, true);
+        this.clickEvent.subscribe(this._onClick, this, true);
+        this.keyDownEvent.subscribe(this._onKeyDown, this, true);
+        this.keyPressEvent.subscribe(this._onKeyPress, this, true);
+
+        YAHOO.widget.Module.textResizeEvent.subscribe(
+            this._onTextResize, 
+            this, 
+            true
+        );
+
+
+        if(p_oConfig) {
+    
+            this.cfg.applyConfig(p_oConfig, true);
+    
+        }
+
+
+        // Register the Menu instance with the MenuManager
+
+        YAHOO.widget.MenuManager.addMenu(this);
+        
+
+        this.initEvent.fire(YAHOO.widget.Menu);
+
+    }
+
+},
+
+
+
+// Private methods
+
+
+/**
+* @method _initSubTree
+* @description Iterates the childNodes of the source element to find nodes 
+* used to instantiate menu and menu items.
+* @private
+*/
+_initSubTree: function() {
+
+    var oNode;
+
+    if(this.srcElement.tagName.toUpperCase() == "DIV") {
+
+        /*
+            Populate the collection of item groups and item
+            group titles
+        */
+
+        oNode = this.body.firstChild;
+
+        var nGroup = 0,
+            sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase();
+
+        do {
+
+            if(oNode && oNode.tagName) {
+
+                switch(oNode.tagName.toUpperCase()) {
+
+                    case sGroupTitleTagName:
+                    
+                        this._aGroupTitleElements[nGroup] = oNode;
+
+                    break;
+
+                    case "UL":
+
+                        this._aListElements[nGroup] = oNode;
+                        this._aItemGroups[nGroup] = [];
+                        nGroup++;
+
+                    break;
+
+                }
+            
+            }
+
+        }
+        while((oNode = oNode.nextSibling));
+
+
+        /*
+            Apply the "first-of-type" class to the first UL to mimic 
+            the "first-of-type" CSS3 psuedo class.
+        */
+
+        if(this._aListElements[0]) {
+
+            Dom.addClass(this._aListElements[0], "first-of-type");
+
+        }
+
+    }
+
+
+    oNode = null;
+
+
+    if(this.srcElement.tagName) {
+
+        var sSrcElementTagName = this.srcElement.tagName.toUpperCase();
+
+
+        switch(sSrcElementTagName) {
+    
+            case "DIV":
+    
+                if(this._aListElements.length > 0) {
+    
+    
+                    var i = this._aListElements.length - 1;
+    
+                    do {
+    
+                        oNode = this._aListElements[i].firstChild;
+        
+    
+                        do {
+        
+                            if(
+                                oNode && 
+                                oNode.tagName && 
+                                oNode.tagName.toUpperCase() == "LI"
+                            ) {
+        
+
+                                this.addItem(
+                                        new this.ITEM_TYPE(
+                                            oNode, 
+                                            { parent: this }
+                                        ), 
+                                        i
+                                    );
+    
+                            }
+                
+                        }
+                        while((oNode = oNode.nextSibling));
+                
+                    }
+                    while(i--);
+    
+                }
+    
+            break;
+    
+            case "SELECT":
+    
+    
+                oNode = this.srcElement.firstChild;
+    
+                do {
+    
+                    if(oNode && oNode.tagName) {
+                    
+                        switch(oNode.tagName.toUpperCase()) {
+        
+                            case "OPTGROUP":
+                            case "OPTION":
+        
+        
+                                this.addItem(
+                                        new this.ITEM_TYPE(
+                                                oNode, 
+                                                { parent: this }
+                                            )
+                                        );
+        
+                            break;
+        
+                        }
+
+                    }
+    
+                }
+                while((oNode = oNode.nextSibling));
+    
+            break;
+    
+        }
+
+    }
+
+},
+
+
+/**
+* @method _getFirstEnabledItem
+* @description Returns the first enabled item in the menu.
+* @return {YAHOO.widget.MenuItem}
+* @private
+*/
+_getFirstEnabledItem: function() {
+
+    var aItems = this.getItems(),
+        nItems = aItems.length,
+        oItem;
+    
+    for(var i=0; i<nItems; i++) {
+
+        oItem = aItems[i];
+
+        if(
+            oItem && 
+            !oItem.cfg.getProperty("disabled") && 
+            oItem.element.style.display != "none"
+        ) {
+
+            return oItem;
+
+        }
+    
+    }
+    
+},
+
+
+/**
+* @method _addItemToGroup
+* @description Adds a menu item to a group.
+* @private
+* @param {Number} p_nGroupIndex Number indicating the group to which the 
+* item belongs.
+* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
+* instance to be added to the menu.
+* @param {String} p_oItem String specifying the text of the item to be added 
+* to the menu.
+* @param {Object} p_oItem Object literal containing a set of menu item 
+* configuration properties.
+* @param {Number} p_nItemIndex Optional. Number indicating the index at 
+* which the menu item should be added.
+* @return {YAHOO.widget.MenuItem}
+*/
+_addItemToGroup: function(p_nGroupIndex, p_oItem, p_nItemIndex) {
+
+    var oItem;
+
+    if(p_oItem instanceof this.ITEM_TYPE) {
+
+        oItem = p_oItem;
+        oItem.parent = this;
+
+    }
+    else if(typeof p_oItem == "string") {
+
+        oItem = new this.ITEM_TYPE(p_oItem, { parent: this });
+    
+    }
+    else if(typeof p_oItem == "object") {
+
+        p_oItem.parent = this;
+
+        oItem = new this.ITEM_TYPE(p_oItem.text, p_oItem);
+
+    }
+
+
+    if(oItem) {
+
+        if (oItem.cfg.getProperty("selected")) {
+
+            this.activeItem = oItem;
+        
+        }
+
+
+        var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0,
+            aGroup = this._getItemGroup(nGroupIndex),
+            oGroupItem;
+
+
+        if(!aGroup) {
+
+            aGroup = this._createItemGroup(nGroupIndex);
+
+        }
+
+
+        if(typeof p_nItemIndex == "number") {
+
+            var bAppend = (p_nItemIndex >= aGroup.length);            
+
+
+            if(aGroup[p_nItemIndex]) {
+    
+                aGroup.splice(p_nItemIndex, 0, oItem);
+    
+            }
+            else {
+    
+                aGroup[p_nItemIndex] = oItem;
+    
+            }
+
+
+            oGroupItem = aGroup[p_nItemIndex];
+
+            if(oGroupItem) {
+
+                if(
+                    bAppend && 
+                    (
+                        !oGroupItem.element.parentNode || 
+                        oGroupItem.element.parentNode.nodeType == 11
+                    )
+                ) {
+        
+                    this._aListElements[nGroupIndex].appendChild(
+                        oGroupItem.element
+                    );
+    
+                }
+                else {
+  
+                    function getNextItemSibling(p_aArray, p_nStartIndex) {
+                
+                            return (
+                                    p_aArray[p_nStartIndex] || 
+                                    getNextItemSibling(
+                                        p_aArray, 
+                                        (p_nStartIndex+1)
+                                    )
+                                );
+
+                    }
+    
+    
+                    var oNextItemSibling = 
+                            getNextItemSibling(aGroup, (p_nItemIndex+1));
+    
+                    if(
+                        oNextItemSibling && 
+                        (
+                            !oGroupItem.element.parentNode || 
+                            oGroupItem.element.parentNode.nodeType == 11
+                        )
+                    ) {
+            
+                        this._aListElements[nGroupIndex].insertBefore(
+                                oGroupItem.element, 
+                                oNextItemSibling.element
+                            );
+        
+                    }
+    
+                }
+    
+
+                oGroupItem.parent = this;
+        
+                this._subscribeToItemEvents(oGroupItem);
+    
+                this._configureSubmenu(oGroupItem);
+                
+                this._updateItemProperties(nGroupIndex);
+        
+
+                this.itemAddedEvent.fire(oGroupItem);
+
+                return oGroupItem;
+    
+            }
+
+        }
+        else {
+    
+            var nItemIndex = aGroup.length;
+    
+            aGroup[nItemIndex] = oItem;
+
+            oGroupItem = aGroup[nItemIndex];
+    
+
+            if(oGroupItem) {
+    
+                if(
+                    !Dom.isAncestor(
+                        this._aListElements[nGroupIndex], 
+                        oGroupItem.element
+                    )
+                ) {
+    
+                    this._aListElements[nGroupIndex].appendChild(
+                        oGroupItem.element
+                    );
+    
+                }
+    
+                oGroupItem.element.setAttribute("groupindex", nGroupIndex);
+                oGroupItem.element.setAttribute("index", nItemIndex);
+        
+                oGroupItem.parent = this;
+    
+                oGroupItem.index = nItemIndex;
+                oGroupItem.groupIndex = nGroupIndex;
+        
+                this._subscribeToItemEvents(oGroupItem);
+    
+                this._configureSubmenu(oGroupItem);
+    
+                if(nItemIndex === 0) {
+        
+                    Dom.addClass(oGroupItem.element, "first-of-type");
+        
+                }
+
+        
+
+                this.itemAddedEvent.fire(oGroupItem);
+
+                return oGroupItem;
+    
+            }
+    
+        }
+
+    }
+    
+},
+
+
+/**
+* @method _removeItemFromGroupByIndex
+* @description Removes a menu item from a group by index.  Returns the menu 
+* item that was removed.
+* @private
+* @param {Number} p_nGroupIndex Number indicating the group to which the menu 
+* item belongs.
+* @param {Number} p_nItemIndex Number indicating the index of the menu item 
+* to be removed.
+* @return {YAHOO.widget.MenuItem}
+*/
+_removeItemFromGroupByIndex: function(p_nGroupIndex, p_nItemIndex) {
+
+    var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0,
+        aGroup = this._getItemGroup(nGroupIndex);
+
+    if(aGroup) {
+
+        var aArray = aGroup.splice(p_nItemIndex, 1),
+            oItem = aArray[0];
+    
+        if(oItem) {
+    
+            // Update the index and className properties of each member        
+            
+            this._updateItemProperties(nGroupIndex);
+    
+            if(aGroup.length === 0) {
+    
+                // Remove the UL
+    
+                var oUL = this._aListElements[nGroupIndex];
+    
+                if(this.body && oUL) {
+    
+                    this.body.removeChild(oUL);
+    
+                }
+    
+                // Remove the group from the array of items
+    
+                this._aItemGroups.splice(nGroupIndex, 1);
+    
+    
+                // Remove the UL from the array of ULs
+    
+                this._aListElements.splice(nGroupIndex, 1);
+    
+    
+                /*
+                     Assign the "first-of-type" class to the new first UL 
+                     in the collection
+                */
+    
+                oUL = this._aListElements[0];
+    
+                if(oUL) {
+    
+                    Dom.addClass(oUL, "first-of-type");
+    
+                }            
+    
+            }
+    
+
+            this.itemRemovedEvent.fire(oItem);    
+
+
+            // Return a reference to the item that was removed
+        
+            return oItem;
+    
+        }
+
+    }
+    
+},
+
+
+/**
+* @method _removeItemFromGroupByValue
+* @description Removes a menu item from a group by reference.  Returns the 
+* menu item that was removed.
+* @private
+* @param {Number} p_nGroupIndex Number indicating the group to which the
+* menu item belongs.
+* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
+* instance to be removed.
+* @return {YAHOO.widget.MenuItem}
+*/    
+_removeItemFromGroupByValue: function(p_nGroupIndex, p_oItem) {
+
+    var aGroup = this._getItemGroup(p_nGroupIndex);
+
+    if(aGroup) {
+
+        var nItems = aGroup.length,
+            nItemIndex = -1;
+    
+        if(nItems > 0) {
+    
+            var i = nItems-1;
+        
+            do {
+        
+                if(aGroup[i] == p_oItem) {
+        
+                    nItemIndex = i;
+                    break;    
+        
+                }
+        
+            }
+            while(i--);
+        
+            if(nItemIndex > -1) {
+        
+                return this._removeItemFromGroupByIndex(
+                            p_nGroupIndex, 
+                            nItemIndex
+                        );
+        
+            }
+    
+        }
+    
+    }
+
+},
+
+
+/**
+* @method _updateItemProperties
+* @description Updates the "index," "groupindex," and "className" properties 
+* of the menu items in the specified group. 
+* @private
+* @param {Number} p_nGroupIndex Number indicating the group of items to update.
+*/
+_updateItemProperties: function(p_nGroupIndex) {
+
+    var aGroup = this._getItemGroup(p_nGroupIndex),
+        nItems = aGroup.length;
+
+    if(nItems > 0) {
+
+        var i = nItems - 1,
+            oItem,
+            oLI;
+
+        // Update the index and className properties of each member
+    
+        do {
+
+            oItem = aGroup[i];
+
+            if(oItem) {
+    
+                oLI = oItem.element;
+
+                oItem.index = i;
+                oItem.groupIndex = p_nGroupIndex;
+
+                oLI.setAttribute("groupindex", p_nGroupIndex);
+                oLI.setAttribute("index", i);
+
+                Dom.removeClass(oLI, "first-of-type");
+
+            }
+    
+        }
+        while(i--);
+
+
+        if(oLI) {
+
+            Dom.addClass(oLI, "first-of-type");
+
+        }
+
+    }
+
+},
+
+
+/**
+* @method _createItemGroup
+* @description Creates a new menu item group (array) and its associated 
+* <code>&#60;ul&#62;</code> element. Returns an aray of menu item groups.
+* @private
+* @param {Number} p_nIndex Number indicating the group to create.
+* @return {Array}
+*/
+_createItemGroup: function(p_nIndex) {
+
+    if(!this._aItemGroups[p_nIndex]) {
+
+        this._aItemGroups[p_nIndex] = [];
+
+        var oUL = document.createElement("ul");
+
+        this._aListElements[p_nIndex] = oUL;
+
+        return this._aItemGroups[p_nIndex];
+
+    }
+
+},
+
+
+/**
+* @method _getItemGroup
+* @description Returns the menu item group at the specified index.
+* @private
+* @param {Number} p_nIndex Number indicating the index of the menu item group 
+* to be retrieved.
+* @return {Array}
+*/
+_getItemGroup: function(p_nIndex) {
+
+    var nIndex = ((typeof p_nIndex == "number") ? p_nIndex : 0);
+
+    return this._aItemGroups[nIndex];
+
+},
+
+
+/**
+* @method _configureSubmenu
+* @description Subscribes the menu item's submenu to its parent menu's events.
+* @private
+* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
+* instance with the submenu to be configured.
+*/
+_configureSubmenu: function(p_oItem) {
+
+    var oSubmenu = p_oItem.cfg.getProperty("submenu");
+
+    if(oSubmenu) {
+            
+        /*
+            Listen for configuration changes to the parent menu 
+            so they they can be applied to the submenu.
+        */
+
+        this.cfg.configChangedEvent.subscribe(
+                this._onParentMenuConfigChange, 
+                oSubmenu, 
+                true
+            );
+
+        this.renderEvent.subscribe(
+                this._onParentMenuRender,
+                oSubmenu, 
+                true
+            );
+
+        oSubmenu.beforeShowEvent.subscribe(
+                this._onSubmenuBeforeShow, 
+                oSubmenu, 
+                true
+            );
+
+        oSubmenu.showEvent.subscribe(this._onSubmenuShow, null, p_oItem);
+        oSubmenu.hideEvent.subscribe(this._onSubmenuHide, null, p_oItem);
+
+    }
+
+},
+
+
+/**
+* @method _subscribeToItemEvents
+* @description Subscribes a menu to a menu item's event.
+* @private
+* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
+* instance whose events should be subscribed to.
+*/
+_subscribeToItemEvents: function(p_oItem) {
+
+    p_oItem.focusEvent.subscribe(this._onMenuItemFocus);
+
+    p_oItem.blurEvent.subscribe(this._onMenuItemBlur);
+
+    p_oItem.cfg.configChangedEvent.subscribe(
+        this._onMenuItemConfigChange,
+        p_oItem,
+        this
+    );
+
+},
+
+
+/**
+* @method _getOffsetWidth
+* @description Returns the offset width of the menu's 
+* <code>&#60;div&#62;</code> element.
+* @private
+*/
+_getOffsetWidth: function() {
+
+    var oClone = this.element.cloneNode(true);
+
+    Dom.setStyle(oClone, "width", "");
+
+    document.body.appendChild(oClone);
+
+    var sWidth = oClone.offsetWidth;
+
+    document.body.removeChild(oClone);
+
+    return sWidth;
+
+},
+
+
+/**
+* @method _setWidth
+* @description Sets the width of the menu's root <code>&#60;div&#62;</code> 
+* element to its offsetWidth.
+* @private
+*/
+_setWidth: function() {
+
+    var sWidth;
+
+    if (this.element.parentNode.tagName.toUpperCase() == "BODY") {
+
+        if (this.browser == "opera") {
+
+            sWidth = this._getOffsetWidth();
+        
+        }
+        else {
+
+            Dom.setStyle(this.element, "width", "auto");
+            
+            sWidth = this.element.offsetWidth;
+        
+        }
+
+    }
+    else {
+    
+        sWidth = this._getOffsetWidth();
+    
+    }
+
+    this.cfg.setProperty("width", (sWidth + "px"));
+
+},
+
+
+/**
+* @method _onWidthChange
+* @description Change event handler for the the menu's "width" configuration
+* property.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onWidthChange: function(p_sType, p_aArgs) {
+
+    var sWidth = p_aArgs[0];
+    
+    if (sWidth && !this._hasSetWidthHandlers) {
+
+        this.itemAddedEvent.subscribe(this._setWidth);
+        this.itemRemovedEvent.subscribe(this._setWidth);
+
+        this._hasSetWidthHandlers = true;
+
+    }
+    else if (this._hasSetWidthHandlers) {
+
+        this.itemAddedEvent.unsubscribe(this._setWidth);
+        this.itemRemovedEvent.unsubscribe(this._setWidth);
+
+        this._hasSetWidthHandlers = false;
+
+    }
+
+},
+
+
+/**
+* @method _onVisibleChange
+* @description Change event handler for the the menu's "visible" configuration
+* property.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onVisibleChange: function(p_sType, p_aArgs) {
+
+    var bVisible = p_aArgs[0];
+    
+    if (bVisible) {
+
+        Dom.addClass(this.element, "visible");
+
+    }
+    else {
+
+        Dom.removeClass(this.element, "visible");
+
+    }
+
+},
+
+
+/**
+* @method _cancelHideDelay
+* @description Cancels the call to "hideMenu."
+* @private
+*/
+_cancelHideDelay: function() {
+
+    var oRoot = this.getRoot();
+
+    if(oRoot._nHideDelayId) {
+
+        window.clearTimeout(oRoot._nHideDelayId);
+
+    }
+
+},
+
+
+/**
+* @method _execHideDelay
+* @description Hides the menu after the number of milliseconds specified by 
+* the "hidedelay" configuration property.
+* @private
+*/
+_execHideDelay: function() {
+
+    this._cancelHideDelay();
+
+    var oRoot = this.getRoot(),
+        me = this;
+
+    function hideMenu() {
+    
+        if(oRoot.activeItem) {
+
+            oRoot.clearActiveItem();
+
+        }
+
+        if(oRoot == me && me.cfg.getProperty("position") == "dynamic") {
+
+            me.hide();            
+        
+        }
+    
+    }
+
+
+    oRoot._nHideDelayId = 
+        window.setTimeout(hideMenu, oRoot.cfg.getProperty("hidedelay"));
+
+},
+
+
+/**
+* @method _cancelShowDelay
+* @description Cancels the call to the "showMenu."
+* @private
+*/
+_cancelShowDelay: function() {
+
+    var oRoot = this.getRoot();
+
+    if(oRoot._nShowDelayId) {
+
+        window.clearTimeout(oRoot._nShowDelayId);
+
+    }
+
+},
+
+
+/**
+* @method _execShowDelay
+* @description Shows the menu after the number of milliseconds specified by 
+* the "showdelay" configuration property have ellapsed.
+* @private
+* @param {YAHOO.widget.Menu} p_oMenu Object specifying the menu that should 
+* be made visible.
+*/
+_execShowDelay: function(p_oMenu) {
+
+    var oRoot = this.getRoot();
+
+    function showMenu() {
+
+        if(p_oMenu.parent.cfg.getProperty("selected")) {
+
+            p_oMenu.show();
+
+        }
+
+    }
+
+
+    oRoot._nShowDelayId = 
+        window.setTimeout(showMenu, oRoot.cfg.getProperty("showdelay"));
+
+},
+
+
+/**
+* @method _execSubmenuHideDelay
+* @description Hides a submenu after the number of milliseconds specified by 
+* the "submenuhidedelay" configuration property have ellapsed.
+* @private
+* @param {YAHOO.widget.Menu} p_oSubmenu Object specifying the submenu that  
+* should be hidden.
+* @param {Number} p_nMouseX The x coordinate of the mouse when it left 
+* the specified submenu's parent menu item.
+* @param {Number} p_nHideDelay The number of milliseconds that should ellapse
+* before the submenu is hidden.
+*/
+_execSubmenuHideDelay: function(p_oSubmenu, p_nMouseX, p_nHideDelay) {
+
+    var me = this;
+
+    p_oSubmenu._nSubmenuHideDelayId = window.setTimeout(function () {
+
+        if(me._nCurrentMouseX > (p_nMouseX + 10)) {
+
+            p_oSubmenu._nSubmenuHideDelayId = window.setTimeout(function () {
+        
+                p_oSubmenu.hide();
+
+            }, p_nHideDelay);
+
+        }
+        else {
+
+            p_oSubmenu.hide();
+        
+        }
+
+    }, 50);
+
+},
+
+
+
+// Protected methods
+
+
+/**
+* @method _disableScrollHeader
+* @description Disables the header used for scrolling the body of the menu.
+* @protected
+*/
+_disableScrollHeader: function() {
+
+    if(!this._bHeaderDisabled) {
+
+        Dom.addClass(this.header, "topscrollbar_disabled");
+        this._bHeaderDisabled = true;
+
+    }
+
+},
+
+
+/**
+* @method _disableScrollFooter
+* @description Disables the footer used for scrolling the body of the menu.
+* @protected
+*/
+_disableScrollFooter: function() {
+
+    if(!this._bFooterDisabled) {
+
+        Dom.addClass(this.footer, "bottomscrollbar_disabled");
+        this._bFooterDisabled = true;
+
+    }
+
+},
+
+
+/**
+* @method _enableScrollHeader
+* @description Enables the header used for scrolling the body of the menu.
+* @protected
+*/
+_enableScrollHeader: function() {
+
+    if(this._bHeaderDisabled) {
+
+        Dom.removeClass(this.header, "topscrollbar_disabled");
+        this._bHeaderDisabled = false;
+
+    }
+
+},
+
+
+/**
+* @method _enableScrollFooter
+* @description Enables the footer used for scrolling the body of the menu.
+* @protected
+*/
+_enableScrollFooter: function() {
+
+    if(this._bFooterDisabled) {
+
+        Dom.removeClass(this.footer, "bottomscrollbar_disabled");
+        this._bFooterDisabled = false;
+
+    }
+
+},
+
+
+/**
+* @method _onMouseOver
+* @description "mouseover" event handler for the menu.
+* @protected
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onMouseOver: function(p_sType, p_aArgs, p_oMenu) {
+
+    if(this._bStopMouseEventHandlers) {
+    
+        return false;
+    
+    }
+
+
+    var oEvent = p_aArgs[0],
+        oItem = p_aArgs[1],
+        oTarget = Event.getTarget(oEvent);
+
+
+    if(
+        !this._bHandledMouseOverEvent && 
+        (oTarget == this.element || Dom.isAncestor(this.element, oTarget))
+    ) {
+
+        // Menu mouseover logic
+
+        this._nCurrentMouseX = 0;
+
+        Event.on(
+                this.element, 
+                "mousemove", 
+                this._onMouseMove, 
+                this, 
+                true
+            );
+
+
+        this.clearActiveItem();
+
+
+        if(this.parent && this._nSubmenuHideDelayId) {
+
+            window.clearTimeout(this._nSubmenuHideDelayId);
+
+            this.parent.cfg.setProperty("selected", true);
+
+            var oParentMenu = this.parent.parent;
+
+            oParentMenu._bHandledMouseOutEvent = true;
+            oParentMenu._bHandledMouseOverEvent = false;
+
+        }
+
+
+        this._bHandledMouseOverEvent = true;
+        this._bHandledMouseOutEvent = false;
+    
+    }
+
+
+    if(
+        oItem && !oItem.handledMouseOverEvent && 
+        !oItem.cfg.getProperty("disabled") && 
+        (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))
+    ) {
+
+        // Menu Item mouseover logic
+
+        var nShowDelay = this.cfg.getProperty("showdelay"),
+            bShowDelay = (nShowDelay > 0);
+
+
+        if(bShowDelay) {
+        
+            this._cancelShowDelay();
+        
+        }
+
+
+        var oActiveItem = this.activeItem;
+    
+        if(oActiveItem) {
+    
+            oActiveItem.cfg.setProperty("selected", false);
+    
+        }
+
+
+        var oItemCfg = oItem.cfg;
+    
+        // Select and focus the current menu item
+    
+        oItemCfg.setProperty("selected", true);
+
+
+        if (this.hasFocus()) {
+        
+            oItem.focus();
+        
+        }
+
+
+        if(this.cfg.getProperty("autosubmenudisplay")) {
+
+            // Show the submenu this menu item
+
+            var oSubmenu = oItemCfg.getProperty("submenu");
+        
+            if(oSubmenu) {
+        
+                if(bShowDelay) {
+
+                    this._execShowDelay(oSubmenu);
+        
+                }
+                else {
+
+                    oSubmenu.show();
+
+                }
+
+            }
+
+        }                        
+
+        oItem.handledMouseOverEvent = true;
+        oItem.handledMouseOutEvent = false;
+
+    }
+
+},
+
+
+/**
+* @method _onMouseOut
+* @description "mouseout" event handler for the menu.
+* @protected
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onMouseOut: function(p_sType, p_aArgs, p_oMenu) {
+
+    if(this._bStopMouseEventHandlers) {
+    
+        return false;
+    
+    }
+
+
+    var oEvent = p_aArgs[0],
+        oItem = p_aArgs[1],
+        oRelatedTarget = Event.getRelatedTarget(oEvent),
+        bMovingToSubmenu = false;
+
+
+    if(oItem && !oItem.cfg.getProperty("disabled")) {
+
+        var oItemCfg = oItem.cfg,
+            oSubmenu = oItemCfg.getProperty("submenu");
+
+
+        if(
+            oSubmenu && 
+            (
+                oRelatedTarget == oSubmenu.element ||
+                Dom.isAncestor(oSubmenu.element, oRelatedTarget)
+            )
+        ) {
+
+            bMovingToSubmenu = true;
+
+        }
+
+
+        if( 
+            !oItem.handledMouseOutEvent && 
+            (
+                (
+                    oRelatedTarget != oItem.element &&  
+                    !Dom.isAncestor(oItem.element, oRelatedTarget)
+                ) || bMovingToSubmenu
+            )
+        ) {
+
+            // Menu Item mouseout logic
+
+            if(!bMovingToSubmenu) {
+
+                oItem.cfg.setProperty("selected", false);
+
+
+                if(oSubmenu) {
+
+                    var nSubmenuHideDelay = 
+                            this.cfg.getProperty("submenuhidedelay"),
+
+                        nShowDelay = this.cfg.getProperty("showdelay");
+
+                    if(
+                        !(this instanceof YAHOO.widget.MenuBar) && 
+                        nSubmenuHideDelay > 0 && 
+                        nShowDelay >= nSubmenuHideDelay
+                    ) {
+
+                        this._execSubmenuHideDelay(
+                                oSubmenu, 
+                                Event.getPageX(oEvent),
+                                nSubmenuHideDelay
+                            );
+
+                    }
+                    else {
+
+                        oSubmenu.hide();
+
+                    }
+
+                }
+
+            }
+
+
+            oItem.handledMouseOutEvent = true;
+            oItem.handledMouseOverEvent = false;
+    
+        }
+
+    }
+
+
+    if(
+        !this._bHandledMouseOutEvent && 
+        (
+            (
+                oRelatedTarget != this.element &&  
+                !Dom.isAncestor(this.element, oRelatedTarget)
+            ) 
+            || bMovingToSubmenu
+        )
+    ) {
+
+        // Menu mouseout logic
+
+        Event.removeListener(this.element, "mousemove", this._onMouseMove);
+
+        this._nCurrentMouseX = Event.getPageX(oEvent);
+
+        this._bHandledMouseOutEvent = true;
+        this._bHandledMouseOverEvent = false;
+
+    }
+
+},
+
+
+/**
+* @method _onMouseMove
+* @description "click" event handler for the menu.
+* @protected
+* @param {Event} p_oEvent Object representing the DOM event object passed 
+* back by the event utility (YAHOO.util.Event).
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onMouseMove: function(p_oEvent, p_oMenu) {
+
+    if(this._bStopMouseEventHandlers) {
+    
+        return false;
+    
+    }
+
+    this._nCurrentMouseX = Event.getPageX(p_oEvent);
+
+},
+
+
+/**
+* @method _onClick
+* @description "click" event handler for the menu.
+* @protected
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onClick: function(p_sType, p_aArgs, p_oMenu) {
+
+    var oEvent = p_aArgs[0],
+        oItem = p_aArgs[1],
+        oTarget = Event.getTarget(oEvent);
+
+    if(oItem && !oItem.cfg.getProperty("disabled")) {
+
+        var oItemCfg = oItem.cfg,
+            oSubmenu = oItemCfg.getProperty("submenu");
+
+
+        /*
+            ACCESSIBILITY FEATURE FOR SCREEN READERS: 
+            Expand/collapse the submenu when the user clicks 
+            on the submenu indicator image.
+        */        
+
+        if(oTarget == oItem.submenuIndicator && oSubmenu) {
+
+            if(oSubmenu.cfg.getProperty("visible")) {
+
+                oSubmenu.hide();
+                
+                oSubmenu.parent.focus();
+    
+            }
+            else {
+
+                this.clearActiveItem();
+
+                oItem.cfg.setProperty("selected", true);
+
+                oSubmenu.show();
+                
+                oSubmenu.setInitialFocus();
+    
+            }
+    
+        }
+        else {
+
+            var sURL = oItemCfg.getProperty("url"),
+                bCurrentPageURL = (sURL.substr((sURL.length-1),1) == "#"),
+                sTarget = oItemCfg.getProperty("target"),
+                bHasTarget = (sTarget && sTarget.length > 0);
+
+            /*
+                Prevent the browser from following links 
+                equal to "#"
+            */
+            
+            if(
+                oTarget.tagName.toUpperCase() == "A" && 
+                bCurrentPageURL && !bHasTarget
+            ) {
+
+                Event.preventDefault(oEvent);
+
+                oItem.focus();
+            
+            }
+
+            if(
+                oTarget.tagName.toUpperCase() != "A" && 
+                !bCurrentPageURL && !bHasTarget
+            ) {
+                
+                /*
+                    Follow the URL of the item regardless of 
+                    whether or not the user clicked specifically
+                    on the anchor element.
+                */
+    
+                document.location = sURL;
+        
+            }
+
+
+            /*
+                If the item doesn't navigate to a URL and it doesn't have
+                a submenu, then collapse the menu tree.
+            */
+
+            if(bCurrentPageURL && !oSubmenu) {
+    
+                var oRoot = this.getRoot();
+                
+                if(oRoot.cfg.getProperty("position") == "static") {
+    
+                    oRoot.clearActiveItem();
+    
+                }
+                else if(oRoot.cfg.getProperty("clicktohide")) {
+
+                    oRoot.hide();
+                
+                }
+    
+            }
+
+        }                    
+    
+    }
+
+},
+
+
+/**
+* @method _onKeyDown
+* @description "keydown" event handler for the menu.
+* @protected
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onKeyDown: function(p_sType, p_aArgs, p_oMenu) {
+
+    var oEvent = p_aArgs[0],
+        oItem = p_aArgs[1],
+        me = this,
+        oSubmenu;
+
+
+    /*
+        This function is called to prevent a bug in Firefox.  In Firefox,
+        moving a DOM element into a stationary mouse pointer will cause the 
+        browser to fire mouse events.  This can result in the menu mouse
+        event handlers being called uncessarily, especially when menus are 
+        moved into a stationary mouse pointer as a result of a 
+        key event handler.
+    */
+    function stopMouseEventHandlers() {
+
+        me._bStopMouseEventHandlers = true;
+        
+        window.setTimeout(function() {
+        
+            me._bStopMouseEventHandlers = false;
+        
+        }, 10);
+
+    }
+
+
+    if(oItem && !oItem.cfg.getProperty("disabled")) {
+
+        var oItemCfg = oItem.cfg,
+            oParentItem = this.parent,
+            oRoot,
+            oNextItem;
+
+
+        switch(oEvent.keyCode) {
+    
+            case 38:    // Up arrow
+            case 40:    // Down arrow
+    
+                oNextItem = (oEvent.keyCode == 38) ? 
+                    oItem.getPreviousEnabledSibling() : 
+                    oItem.getNextEnabledSibling();
+        
+                if(oNextItem) {
+
+                    this.clearActiveItem();
+
+                    oNextItem.cfg.setProperty("selected", true);
+                    oNextItem.focus();
+
+
+                    if(this.cfg.getProperty("maxheight") > 0) {
+
+                        var oBody = this.body;
+
+                        oBody.scrollTop = 
+
+                            (
+                                oNextItem.element.offsetTop + 
+                                oNextItem.element.offsetHeight
+                            ) - oBody.offsetHeight;
+
+
+                        var nScrollTop = oBody.scrollTop,
+                            nScrollTarget = 
+                                oBody.scrollHeight - oBody.offsetHeight;
+
+                        if(nScrollTop === 0) {
+
+                            this._disableScrollHeader();
+                            this._enableScrollFooter();
+
+                        }
+                        else if(nScrollTop == nScrollTarget) {
+
+                             this._enableScrollHeader();
+                             this._disableScrollFooter();
+
+                        }
+                        else {
+
+                            this._enableScrollHeader();
+                            this._enableScrollFooter();
+
+                        }
+
+                    }
+
+                }
+
+    
+                Event.preventDefault(oEvent);
+
+                stopMouseEventHandlers();
+    
+            break;
+            
+    
+            case 39:    // Right arrow
+    
+                oSubmenu = oItemCfg.getProperty("submenu");
+    
+                if(oSubmenu) {
+    
+                    if(!oItemCfg.getProperty("selected")) {
+        
+                        oItemCfg.setProperty("selected", true);
+        
+                    }
+    
+                    oSubmenu.show();
+                    oSubmenu.setInitialFocus();
+                    oSubmenu.setInitialSelection();
+    
+                }
+                else {
+    
+                    oRoot = this.getRoot();
+                    
+                    if(oRoot instanceof YAHOO.widget.MenuBar) {
+    
+                        oNextItem = oRoot.activeItem.getNextEnabledSibling();
+    
+                        if(oNextItem) {
+                        
+                            oRoot.clearActiveItem();
+    
+                            oNextItem.cfg.setProperty("selected", true);
+    
+                            oSubmenu = oNextItem.cfg.getProperty("submenu");
+    
+                            if(oSubmenu) {
+    
+                                oSubmenu.show();
+                            
+                            }
+    
+                            oNextItem.focus();
+                        
+                        }
+                    
+                    }
+                
+                }
+    
+    
+                Event.preventDefault(oEvent);
+
+                stopMouseEventHandlers();
+
+            break;
+    
+    
+            case 37:    // Left arrow
+    
+                if(oParentItem) {
+    
+                    var oParentMenu = oParentItem.parent;
+    
+                    if(oParentMenu instanceof YAHOO.widget.MenuBar) {
+    
+                        oNextItem = 
+                            oParentMenu.activeItem.getPreviousEnabledSibling();
+    
+                        if(oNextItem) {
+                        
+                            oParentMenu.clearActiveItem();
+    
+                            oNextItem.cfg.setProperty("selected", true);
+    
+                            oSubmenu = oNextItem.cfg.getProperty("submenu");
+    
+                            if(oSubmenu) {
+                            
+                                oSubmenu.show();
+                            
+                            }
+    
+                            oNextItem.focus();
+                        
+                        } 
+                    
+                    }
+                    else {
+    
+                        this.hide();
+    
+                        oParentItem.focus();
+                    
+                    }
+    
+                }
+    
+                Event.preventDefault(oEvent);
+
+                stopMouseEventHandlers();
+
+            break;        
+    
+        }
+
+
+    }
+
+
+    if(oEvent.keyCode == 27) { // Esc key
+
+        if(this.cfg.getProperty("position") == "dynamic") {
+        
+            this.hide();
+
+            if(this.parent) {
+
+                this.parent.focus();
+            
+            }
+
+        }
+        else if(this.activeItem) {
+
+            oSubmenu = this.activeItem.cfg.getProperty("submenu");
+
+            if(oSubmenu && oSubmenu.cfg.getProperty("visible")) {
+            
+                oSubmenu.hide();
+                this.activeItem.focus();
+            
+            }
+            else {
+
+                this.activeItem.blur();
+                this.activeItem.cfg.setProperty("selected", false);
+        
+            }
+        
+        }
+
+
+        Event.preventDefault(oEvent);
+    
+    }
+    
+},
+
+
+/**
+* @method _onKeyPress
+* @description "keypress" event handler for a Menu instance.
+* @protected
+* @param {String} p_sType The name of the event that was fired.
+* @param {Array} p_aArgs Collection of arguments sent when the event 
+* was fired.
+* @param {YAHOO.widget.Menu} p_oMenu The Menu instance that fired the event.
+*/
+_onKeyPress: function(p_sType, p_aArgs, p_oMenu) {
+    
+    var oEvent = p_aArgs[0];
+
+
+    if(oEvent.keyCode == 40 || oEvent.keyCode == 38) {
+
+        YAHOO.util.Event.preventDefault(oEvent);
+
+    }
+
+},
+
+
+/**
+* @method _onTextResize
+* @description "textresize" event handler for the menu.
+* @protected
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onTextResize: function(p_sType, p_aArgs, p_oMenu) {
+
+    if(this.browser == "gecko" && !this._handleResize) {
+
+        this._handleResize = true;
+        return;
+    
+    }
+
+
+    var oConfig = this.cfg;
+
+    if(oConfig.getProperty("position") == "dynamic") {
+
+        oConfig.setProperty("width", (this._getOffsetWidth() + "px"));
+
+    }
+
+},
+
+
+/**
+* @method _onScrollTargetMouseOver
+* @description "mouseover" event handler for the menu's "header" and "footer" 
+* elements.  Used to scroll the body of the menu up and down when the 
+* menu's "maxheight" configuration property is set to a value greater than 0.
+* @protected
+* @param {Event} p_oEvent Object representing the DOM event object passed 
+* back by the event utility (YAHOO.util.Event).
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onScrollTargetMouseOver: function(p_oEvent, p_oMenu) {
+
+    this._cancelHideDelay();
+
+    var oTarget = Event.getTarget(p_oEvent),
+        oBody = this.body,
+        me = this,
+        nScrollTarget,
+        fnScrollFunction;
+
+
+    function scrollBodyDown() {
+
+        var nScrollTop = oBody.scrollTop;
+
+
+        if(nScrollTop < nScrollTarget) {
+
+            oBody.scrollTop = (nScrollTop + 1);
+
+            me._enableScrollHeader();
+
+        }
+        else {
+
+            oBody.scrollTop = nScrollTarget;
+            
+            window.clearInterval(me._nBodyScrollId);
+
+            me._disableScrollFooter();
+
+        }
+
+    }
+
+
+    function scrollBodyUp() {
+
+        var nScrollTop = oBody.scrollTop;
+
+
+        if(nScrollTop > 0) {
+
+            oBody.scrollTop = (nScrollTop - 1);
+
+            me._enableScrollFooter();
+
+        }
+        else {
+
+            oBody.scrollTop = 0;
+            
+            window.clearInterval(me._nBodyScrollId);
+
+            me._disableScrollHeader();
+
+        }
+
+    }
+
+    
+    if(Dom.hasClass(oTarget, "hd")) {
+
+        fnScrollFunction = scrollBodyUp;
+    
+    }
+    else {
+
+        nScrollTarget = oBody.scrollHeight - oBody.offsetHeight;
+
+        fnScrollFunction = scrollBodyDown;
+    
+    }
+
+
+    this._nBodyScrollId = window.setInterval(fnScrollFunction, 10);
+
+},
+
+
+/**
+* @method _onScrollTargetMouseOut
+* @description "mouseout" event handler for the menu's "header" and "footer" 
+* elements.  Used to stop scrolling the body of the menu up and down when the 
+* menu's "maxheight" configuration property is set to a value greater than 0.
+* @protected
+* @param {Event} p_oEvent Object representing the DOM event object passed 
+* back by the event utility (YAHOO.util.Event).
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onScrollTargetMouseOut: function(p_oEvent, p_oMenu) {
+
+    window.clearInterval(this._nBodyScrollId);
+
+    this._cancelHideDelay();
+
+},
+
+
+
+// Private methods
+
+
+/**
+* @method _onInit
+* @description "init" event handler for the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onInit: function(p_sType, p_aArgs, p_oMenu) {
+
+    this.cfg.subscribeToConfigEvent("width", this._onWidthChange);
+    this.cfg.subscribeToConfigEvent("visible", this._onVisibleChange);
+
+    if(
+        (
+            (this.parent && !this.lazyLoad) || 
+            (!this.parent && this.cfg.getProperty("position") == "static") ||
+            (
+                !this.parent && 
+                !this.lazyLoad && 
+                this.cfg.getProperty("position") == "dynamic"
+            ) 
+        ) && 
+        this.getItemGroups().length === 0
+    ) {
+ 
+        if(this.srcElement) {
+
+            this._initSubTree();
+        
+        }
+
+
+        if(this.itemData) {
+
+            this.addItems(this.itemData);
+
+        }
+    
+    }
+    else if(this.lazyLoad) {
+
+        this.cfg.fireQueue();
+    
+    }
+
+},
+
+
+/**
+* @method _onBeforeRender
+* @description "beforerender" event handler for the menu.  Appends all of the 
+* <code>&#60;ul&#62;</code>, <code>&#60;li&#62;</code> and their accompanying 
+* title elements to the body element of the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onBeforeRender: function(p_sType, p_aArgs, p_oMenu) {
+
+    var oConfig = this.cfg,
+        oEl = this.element,
+        nListElements = this._aListElements.length;
+
+
+    if(nListElements > 0) {
+
+        var i = 0,
+            bFirstList = true,
+            oUL,
+            oGroupTitle;
+
+
+        do {
+
+            oUL = this._aListElements[i];
+
+            if(oUL) {
+
+                if(bFirstList) {
+        
+                    Dom.addClass(oUL, "first-of-type");
+                    bFirstList = false;
+        
+                }
+
+
+                if(!Dom.isAncestor(oEl, oUL)) {
+
+                    this.appendToBody(oUL);
+
+                }
+
+
+                oGroupTitle = this._aGroupTitleElements[i];
+
+                if(oGroupTitle) {
+
+                    if(!Dom.isAncestor(oEl, oGroupTitle)) {
+
+                        oUL.parentNode.insertBefore(oGroupTitle, oUL);
+
+                    }
+
+
+                    Dom.addClass(oUL, "hastitle");
+
+                }
+
+            }
+
+            i++;
+
+        }
+        while(i < nListElements);
+
+    }
+
+},
+
+
+/**
+* @method _onRender
+* @description "render" event handler for the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onRender: function(p_sType, p_aArgs) {
+
+    if (
+        this.cfg.getProperty("position") == "dynamic" && 
+        !this.cfg.getProperty("width")
+    ) {
+
+        this._setWidth();
+    
+    }
+
+},
+
+
+/**
+* @method _onBeforeShow
+* @description "beforeshow" event handler for the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+_onBeforeShow: function(p_sType, p_aArgs, p_oMenu) {
+
+    if(this.lazyLoad && this.getItemGroups().length === 0) {
+
+        if(this.srcElement) {
+        
+            this._initSubTree();
+
+        }
+
+
+        if(this.itemData) {
+
+            if(
+                this.parent && this.parent.parent && 
+                this.parent.parent.srcElement && 
+                this.parent.parent.srcElement.tagName.toUpperCase() == "SELECT"
+            ) {
+
+                var nOptions = this.itemData.length;
+    
+                for(var n=0; n<nOptions; n++) {
+
+                    if(this.itemData[n].tagName) {
+
+                        this.addItem((new this.ITEM_TYPE(this.itemData[n])));
+    
+                    }
+    
+                }
+            
+            }
+            else {
+
+                this.addItems(this.itemData);
+            
+            }
+        
+        }
+
+
+        var oSrcElement = this.srcElement;
+
+        if(oSrcElement) {
+
+            if(oSrcElement.tagName.toUpperCase() == "SELECT") {
+
+                if(Dom.inDocument(oSrcElement)) {
+
+                    this.render(oSrcElement.parentNode);
+                
+                }
+                else {
+                
+                    this.render(this.cfg.getProperty("container"));
+                
+                }
+
+            }
+            else {
+
+                this.render();
+
+            }
+
+        }
+        else {
+
+            if(this.parent) {
+
+                this.render(this.parent.element);            
+
+            }
+            else {
+
+                this.render(this.cfg.getProperty("container"));
+                this.cfg.refireEvent("xy");
+
+            }                
+
+        }
+
+    }
+
+
+    if(this.cfg.getProperty("position") == "dynamic") {
+
+        var nViewportHeight = Dom.getViewportHeight();
+
+
+        if(this.parent && this.parent.parent instanceof YAHOO.widget.MenuBar) {
+           
+            var oRegion = YAHOO.util.Region.getRegion(this.parent.element);
+            
+            nViewportHeight = (nViewportHeight - oRegion.bottom);
+
+        }
+
+
+        if(this.element.offsetHeight >= nViewportHeight) {
+    
+            var nMaxHeight = this.cfg.getProperty("maxheight");
+
+            /*
+                Cache the original value for the "maxheight" configuration  
+                property so that we can set it back when the menu is hidden.
+            */
+    
+            this._nMaxHeight = nMaxHeight;
+
+            this.cfg.setProperty("maxheight", (nViewportHeight - 20));
+        
+        }
+    
+    
+        if(this.cfg.getProperty("maxheight") > 0) {
+    
+            var oBody = this.body;
+    
+            if(oBody.scrollTop > 0) {
+    
+                oBody.scrollTop = 0;
+    
+            }
+
+            this._disableScrollHeader();
+            this._enableScrollFooter();
+    
+        }
+
+    }
+
+
+},
+
+
+/**
+* @method _onShow
+* @description "show" event handler for the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that fired 
+* the event.
+*/
+_onShow: function(p_sType, p_aArgs, p_oMenu) {
+
+    var oParent = this.parent;
+    
+    if(oParent) {
+
+        var oParentMenu = oParent.parent,
+            aParentAlignment = oParentMenu.cfg.getProperty("submenualignment"),
+            aAlignment = this.cfg.getProperty("submenualignment");
+
+
+        if(
+            (aParentAlignment[0] != aAlignment[0]) &&
+            (aParentAlignment[1] != aAlignment[1])
+        ) {
+
+            this.cfg.setProperty(
+                "submenualignment", 
+                [ aParentAlignment[0], aParentAlignment[1] ]
+            );
+        
+        }
+
+
+        if(
+            !oParentMenu.cfg.getProperty("autosubmenudisplay") && 
+            oParentMenu.cfg.getProperty("position") == "static"
+        ) {
+
+            oParentMenu.cfg.setProperty("autosubmenudisplay", true);
+
+
+            function disableAutoSubmenuDisplay(p_oEvent) {
+
+                if(
+                    p_oEvent.type == "mousedown" || 
+                    (p_oEvent.type == "keydown" && p_oEvent.keyCode == 27)
+                ) {
+
+                    /*  
+                        Set the "autosubmenudisplay" to "false" if the user
+                        clicks outside the menu bar.
+                    */
+
+                    var oTarget = Event.getTarget(p_oEvent);
+
+                    if(
+                        oTarget != oParentMenu.element || 
+                        !YAHOO.util.Dom.isAncestor(oParentMenu.element, oTarget)
+                    ) {
+
+                        oParentMenu.cfg.setProperty(
+                            "autosubmenudisplay", 
+                            false
+                        );
+
+                        Event.removeListener(
+                                document, 
+                                "mousedown", 
+                                disableAutoSubmenuDisplay
+                            );
+
+                        Event.removeListener(
+                                document, 
+                                "keydown", 
+                                disableAutoSubmenuDisplay
+                            );
+
+                    }
+                
+                }
+
+            }
+
+            Event.on(document, "mousedown", disableAutoSubmenuDisplay);                             
+            Event.on(document, "keydown", disableAutoSubmenuDisplay);
+
+        }
+
+    }
+
+},
+
+
+/**
+* @method _onBeforeHide
+* @description "beforehide" event handler for the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that fired 
+* the event.
+*/
+_onBeforeHide: function(p_sType, p_aArgs, p_oMenu) {
+
+    var oActiveItem = this.activeItem;
+
+    if(oActiveItem) {
+
+        var oConfig = oActiveItem.cfg;
+
+        oConfig.setProperty("selected", false);
+
+        var oSubmenu = oConfig.getProperty("submenu");
+
+        if(oSubmenu) {
+
+            oSubmenu.hide();
+
+        }
+
+    }
+
+    if (this == this.getRoot()) {
+
+        this.blur();
+    
+    }
+
+},
+
+
+/**
+* @method _onHide
+* @description "hide" event handler for the menu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that fired 
+* the event.
+*/
+_onHide: function(p_sType, p_aArgs, p_oMenu) {
+
+    if(this._nMaxHeight != -1) {
+
+        this.cfg.setProperty("maxheight", this._nMaxHeight);
+
+        this._nMaxHeight = -1;
+
+    }
+
+},
+
+
+/**
+* @method _onParentMenuConfigChange
+* @description "configchange" event handler for a submenu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that 
+* subscribed to the event.
+*/
+_onParentMenuConfigChange: function(p_sType, p_aArgs, p_oSubmenu) {
+    
+    var sPropertyName = p_aArgs[0][0],
+        oPropertyValue = p_aArgs[0][1];
+
+    switch(sPropertyName) {
+
+        case "iframe":
+        case "constraintoviewport":
+        case "hidedelay":
+        case "showdelay":
+        case "submenuhidedelay":
+        case "clicktohide":
+        case "effect":
+        case "classname":
+
+            p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
+                
+        break;        
+        
+    }
+    
+},
+
+
+/**
+* @method _onParentMenuRender
+* @description "render" event handler for a submenu.  Renders a  
+* submenu in response to the firing of its parent's "render" event.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that 
+* subscribed to the event.
+*/
+_onParentMenuRender: function(p_sType, p_aArgs, p_oSubmenu) {
+
+    var oParentMenu = p_oSubmenu.parent.parent,
+
+        oConfig = {
+
+            constraintoviewport: 
+                oParentMenu.cfg.getProperty("constraintoviewport"),
+
+            xy: [0,0],
+                
+            clicktohide: oParentMenu.cfg.getProperty("clicktohide"),
+                
+            effect: oParentMenu.cfg.getProperty("effect"),
+
+            showdelay: oParentMenu.cfg.getProperty("showdelay"),
+            
+            hidedelay: oParentMenu.cfg.getProperty("hidedelay"),
+
+            submenuhidedelay: oParentMenu.cfg.getProperty("submenuhidedelay"),
+
+            classname: oParentMenu.cfg.getProperty("classname")
+
+        };
+
+
+    /*
+        Only sync the "iframe" configuration property if the parent
+        menu's "position" configuration is the same.
+    */
+
+    if(
+        this.cfg.getProperty("position") == 
+        oParentMenu.cfg.getProperty("position")
+    ) {
+
+        oConfig.iframe = oParentMenu.cfg.getProperty("iframe");
+    
+    }
+               
+
+    p_oSubmenu.cfg.applyConfig(oConfig);
+
+
+    if(!this.lazyLoad) {
+
+        var oLI = this.parent.element;
+
+        if(this.element.parentNode == oLI) {
+    
+            this.render();
+    
+        }
+        else {
+
+            this.render(oLI);
+    
+        }
+
+    }
+    
+},
+
+
+/**
+* @method _onSubmenuBeforeShow
+* @description "beforeshow" event handler for a submenu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that 
+* subscribed to the event.
+*/
+_onSubmenuBeforeShow: function(p_sType, p_aArgs, p_oSubmenu) {
+    
+    var oParent = this.parent,
+        aAlignment = oParent.parent.cfg.getProperty("submenualignment");
+
+    this.cfg.setProperty(
+        "context", 
+        [oParent.element, aAlignment[0], aAlignment[1]]
+    );
+
+
+    var nScrollTop = oParent.parent.body.scrollTop;
+
+    if(
+        (this.browser == "gecko" || this.browser == "safari") 
+        && nScrollTop > 0
+    ) {
+
+         this.cfg.setProperty("y", (this.cfg.getProperty("y") - nScrollTop));
+    
+    }
+
+},
+
+
+/**
+* @method _onSubmenuShow
+* @description "show" event handler for a submenu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onSubmenuShow: function(p_sType, p_aArgs) {
+    
+    this.submenuIndicator.firstChild.nodeValue = 
+        this.EXPANDED_SUBMENU_INDICATOR_TEXT;
+
+},
+
+
+/**
+* @method _onSubmenuHide
+* @description "hide" Custom Event handler for a submenu.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onSubmenuHide: function(p_sType, p_aArgs) {
+    
+    this.submenuIndicator.firstChild.nodeValue =
+        this.COLLAPSED_SUBMENU_INDICATOR_TEXT;
+
+},
+
+
+/**
+* @method _onMenuItemFocus
+* @description "focus" event handler for the menu's items.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onMenuItemFocus: function(p_sType, p_aArgs) {
+
+    this.parent.focusEvent.fire(this);
+
+},
+
+
+/**
+* @method _onMenuItemBlur
+* @description "blur" event handler for the menu's items.
+* @private
+* @param {String} p_sType String representing the name of the event 
+* that was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+*/
+_onMenuItemBlur: function(p_sType, p_aArgs) {
+
+    this.parent.blurEvent.fire(this);
+
+},
+
+
+/**
+* @method _onMenuItemConfigChange
+* @description "configchange" event handler for the menu's items.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item 
+* that fired the event.
+*/
+_onMenuItemConfigChange: function(p_sType, p_aArgs, p_oItem) {
+
+    var sPropertyName = p_aArgs[0][0],
+        oPropertyValue = p_aArgs[0][1];
+
+    switch(sPropertyName) {
+
+        case "selected":
+
+            if (oPropertyValue === true) {
+
+                this.activeItem = p_oItem;
+            
+            }
+
+        break;
+
+        case "submenu":
+
+            var oSubmenu = p_aArgs[0][1];
+
+            if(oSubmenu) {
+
+                this._configureSubmenu(p_oItem);
+
+            }
+
+        break;
+
+        case "text":
+        case "helptext":
+
+            /*
+                A change to an item's "text" or "helptext"
+                configuration properties requires the width of the parent
+                menu to be recalculated.
+            */
+
+            if(this.element.style.width) {
+    
+                var sWidth = this._getOffsetWidth() + "px";
+
+                Dom.setStyle(this.element, "width", sWidth);
+
+            }
+
+        break;
+
+    }
+
+},
+
+
+
+// Public event handlers for configuration properties
+
+
+/**
+* @method enforceConstraints
+* @description The default event handler executed when the moveEvent is fired,  
+* if the "constraintoviewport" configuration property is set to true.
+* @param {String} type The name of the event that was fired.
+* @param {Array} args Collection of arguments sent when the 
+* event was fired.
+* @param {Array} obj Array containing the current Menu instance 
+* and the item that fired the event.
+*/
+enforceConstraints: function(type, args, obj) {
+
+    if(this.parent && !(this.parent.parent instanceof YAHOO.widget.MenuBar)) {
+    
+        var oConfig = this.cfg,
+            pos = args[0],
+            
+            x = pos[0],
+            y = pos[1],
+            
+            offsetHeight = this.element.offsetHeight,
+            offsetWidth = this.element.offsetWidth,
+            
+            viewPortWidth = YAHOO.util.Dom.getViewportWidth(),
+            viewPortHeight = YAHOO.util.Dom.getViewportHeight(),
+            
+            scrollX = Math.max(
+                    document.documentElement.scrollLeft, 
+                    document.body.scrollLeft
+                ),
+            
+            scrollY = Math.max(
+                    document.documentElement.scrollTop, 
+                    document.body.scrollTop
+                ),
+            
+            nPadding = (
+                            this.parent && 
+                            this.parent.parent instanceof YAHOO.widget.MenuBar
+                        ) ? 0 : 10,
+            
+            topConstraint = scrollY + nPadding,
+            leftConstraint = scrollX + nPadding,
+            bottomConstraint = 
+                scrollY + viewPortHeight - offsetHeight - nPadding,
+            rightConstraint = scrollX + viewPortWidth - offsetWidth - nPadding,
+            
+            aContext = oConfig.getProperty("context"),
+            oContextElement = aContext ? aContext[0] : null;
+    
+    
+        if (x < 10) {
+    
+            x = leftConstraint;
+    
+        } else if ((x + offsetWidth) > viewPortWidth) {
+    
+            if(
+                oContextElement &&
+                ((x - oContextElement.offsetWidth) > offsetWidth)
+            ) {
+    
+                x = (x - (oContextElement.offsetWidth + offsetWidth));
+    
+            }
+            else {
+    
+                x = rightConstraint;
+    
+            }
+    
+        }
+    
+        if (y < 10) {
+    
+            y = topConstraint;
+    
+        } else if (y > bottomConstraint) {
+    
+            if(oContextElement && (y > offsetHeight)) {
+    
+                y = ((y + oContextElement.offsetHeight) - offsetHeight);
+    
+            }
+            else {
+    
+                y = bottomConstraint;
+    
+            }
+    
+        }
+    
+        oConfig.setProperty("x", x, true);
+        oConfig.setProperty("y", y, true);
+        oConfig.setProperty("xy", [x,y], true);
+    
+    }
+
+},
+
+
+/**
+* @method configVisible
+* @description Event handler for when the "visible" configuration property 
+* the menu changes.
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+configVisible: function(p_sType, p_aArgs, p_oMenu) {
+
+    if(this.cfg.getProperty("position") == "dynamic") {
+
+        YAHOO.widget.Menu.superclass.configVisible.call(
+            this, 
+            p_sType, 
+            p_aArgs, 
+            p_oMenu
+        );
+
+    }
+    else {
+
+        var bVisible = p_aArgs[0],
+    	    sDisplay = Dom.getStyle(this.element, "display");
+
+        if(bVisible) {
+
+            if(sDisplay != "block") {
+                this.beforeShowEvent.fire();
+                Dom.setStyle(this.element, "display", "block");
+                this.showEvent.fire();
+            }
+        
+        }
+        else {
+
+			if(sDisplay == "block") {
+				this.beforeHideEvent.fire();
+				Dom.setStyle(this.element, "display", "none");
+				this.hideEvent.fire();
+			}
+        
+        }
+
+    }
+
+},
+
+
+/**
+* @method configPosition
+* @description Event handler for when the "position" configuration property 
+* of the menu changes.
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+configPosition: function(p_sType, p_aArgs, p_oMenu) {
+
+    var sCSSPosition = p_aArgs[0] == "static" ? "static" : "absolute",
+        oCfg = this.cfg;
+
+    Dom.setStyle(this.element, "position", sCSSPosition);
+
+
+    if(sCSSPosition == "static") {
+
+        /*
+            Remove the iframe for statically positioned menus since it will 
+            intercept mouse events.
+        */
+
+        oCfg.setProperty("iframe", false);
+
+
+        // Statically positioned menus are visible by default
+        
+        Dom.setStyle(this.element, "display", "block");
+
+        oCfg.setProperty("visible", true);
+
+    }
+    else {
+
+        /*
+            Even though the "visible" property is queued to 
+            "false" by default, we need to set the "visibility" property to 
+            "hidden" since Overlay's "configVisible" implementation checks the 
+            element's "visibility" style property before deciding whether 
+            or not to show an Overlay instance.
+        */
+
+        Dom.setStyle(this.element, "visibility", "hidden");
+    
+    }
+
+
+    if(sCSSPosition == "absolute") {
+
+        var nZIndex = oCfg.getProperty("zindex");
+
+        if(!nZIndex || nZIndex === 0) {
+
+            nZIndex = this.parent ? 
+                (this.parent.parent.cfg.getProperty("zindex") + 1) : 1;
+
+            oCfg.setProperty("zindex", nZIndex);
+
+        }
+
+    }
+
+},
+
+
+/**
+* @method configIframe
+* @description Event handler for when the "iframe" configuration property of 
+* the menu changes.
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+configIframe: function(p_sType, p_aArgs, p_oMenu) {    
+
+    if(this.cfg.getProperty("position") == "dynamic") {
+
+        YAHOO.widget.Menu.superclass.configIframe.call(
+            this, 
+            p_sType, 
+            p_aArgs, 
+            p_oMenu
+        );
+
+    }
+
+},
+
+
+/**
+* @method configHideDelay
+* @description Event handler for when the "hidedelay" configuration property 
+* of the menu changes.
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+configHideDelay: function(p_sType, p_aArgs, p_oMenu) {
+
+    var nHideDelay = p_aArgs[0],
+        oMouseOutEvent = this.mouseOutEvent,
+        oMouseOverEvent = this.mouseOverEvent,
+        oKeyDownEvent = this.keyDownEvent;
+
+    if(nHideDelay > 0) {
+
+        /*
+            Only assign event handlers once. This way the user change 
+            the value for the hidedelay as many times as they want.
+        */
+
+        if(!this._bHideDelayEventHandlersAssigned) {
+
+            oMouseOutEvent.subscribe(this._execHideDelay, this);
+            oMouseOverEvent.subscribe(this._cancelHideDelay, this, true);
+            oKeyDownEvent.subscribe(this._cancelHideDelay, this, true);
+
+            this._bHideDelayEventHandlersAssigned = true;
+        
+        }
+
+    }
+    else {
+
+        oMouseOutEvent.unsubscribe(this._execHideDelay, this);
+        oMouseOverEvent.unsubscribe(this._cancelHideDelay, this);
+        oKeyDownEvent.unsubscribe(this._cancelHideDelay, this);
+
+        this._bHideDelayEventHandlersAssigned = false;
+
+    }
+
+},
+
+
+/**
+* @method configContainer
+* @description Event handler for when the "container" configuration property 
+of the menu changes.
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that 
+* fired the event.
+*/
+configContainer: function(p_sType, p_aArgs, p_oMenu) {
+
+	var oElement = p_aArgs[0];
+
+	if(typeof oElement == 'string') {
+
+        this.cfg.setProperty(
+                "container", 
+                document.getElementById(oElement), 
+                true
+            );
+
+	}
+
+},
+
+
+/**
+* @method _setMaxHeight
+* @description "renderEvent" handler used to defer the setting of the 
+* "maxheight" configuration property until the menu is rendered in lazy 
+* load scenarios.
+* @param {String} p_sType The name of the event that was fired.
+* @param {Array} p_aArgs Collection of arguments sent when the event 
+* was fired.
+* @param {Number} p_nMaxHeight Number representing the value to set for the 
+* "maxheight" configuration property.
+* @private
+*/
+_setMaxHeight: function(p_sType, p_aArgs, p_nMaxHeight) {
+
+    this.cfg.setProperty("maxheight", p_nMaxHeight);
+    this.renderEvent.unsubscribe(this._setMaxHeight);
+
+},
+
+
+/**
+* @method configMaxHeight
+* @description Event handler for when the "maxheight" configuration property of 
+* a Menu changes.
+* @param {String} p_sType The name of the event that was fired.
+* @param {Array} p_aArgs Collection of arguments sent when the event 
+* was fired.
+* @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired
+* the event.
+*/
+configMaxHeight: function(p_sType, p_aArgs, p_oMenu) {
+
+    var nMaxHeight = p_aArgs[0],
+        oBody = this.body;
+
+
+    if(this.lazyLoad && !oBody) {
+
+        this.renderEvent.unsubscribe(this._setMaxHeight);
+    
+        if(nMaxHeight > 0) {
+
+            this.renderEvent.subscribe(this._setMaxHeight, nMaxHeight, this);
+
+        }
+
+        return;
+    
+    }
+
+    Dom.setStyle(oBody, "height", "auto");
+    Dom.setStyle(oBody, "overflow", "visible");    
+
+    var oHeader = this.header,
+        oFooter = this.footer,
+        fnMouseOver = this._onScrollTargetMouseOver,
+        fnMouseOut = this._onScrollTargetMouseOut;
+
+
+    if((nMaxHeight > 0) && (oBody.offsetHeight > nMaxHeight)) {
+
+        if(!this.cfg.getProperty("width")) {
+
+            this._setWidth();
+
+        }
+
+        if(!oHeader && !oFooter) {
+
+            this.setHeader("&#32;");
+            this.setFooter("&#32;");
+
+            oHeader = this.header;
+            oFooter = this.footer;
+
+            Dom.addClass(oHeader, "topscrollbar");
+            Dom.addClass(oFooter, "bottomscrollbar");
+            
+            this.element.insertBefore(oHeader, oBody);
+            this.element.appendChild(oFooter);
+
+            Event.on(oHeader, "mouseover", fnMouseOver, this, true);
+            Event.on(oHeader, "mouseout", fnMouseOut, this, true);
+            Event.on(oFooter, "mouseover", fnMouseOver, this, true);
+            Event.on(oFooter, "mouseout", fnMouseOut, this, true);
+        
+        }
+
+        var nHeight = 
+
+                (
+                    nMaxHeight - 
+                    (this.footer.offsetHeight + this.header.offsetHeight)
+                );
+
+        Dom.setStyle(oBody, "height", (nHeight + "px"));
+        Dom.setStyle(oBody, "overflow", "hidden");
+
+    }
+    else if(oHeader && oFooter) {
+
+        Dom.setStyle(oBody, "height", "auto");
+        Dom.setStyle(oBody, "overflow", "visible");
+
+        Event.removeListener(oHeader, "mouseover", fnMouseOver);
+        Event.removeListener(oHeader, "mouseout", fnMouseOut);
+        Event.removeListener(oFooter, "mouseover", fnMouseOver);
+        Event.removeListener(oFooter, "mouseout", fnMouseOut);
+
+        this.element.removeChild(oHeader);
+        this.element.removeChild(oFooter);
+    
+        this.header = null;
+        this.footer = null;
+    
+    }
+
+},
+
+
+/**
+* @method configClassName
+* @description Event handler for when the "classname" configuration property of 
+* a menu changes.
+* @param {String} p_sType The name of the event that was fired.
+* @param {Array} p_aArgs Collection of arguments sent when the event was fired.
+* @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
+*/
+configClassName: function(p_sType, p_aArgs, p_oMenu) {
+
+    var sClassName = p_aArgs[0];
+
+    if(this._sClassName) {
+
+        Dom.removeClass(this.element, this._sClassName);
+
+    }
+
+    Dom.addClass(this.element, sClassName);
+    this._sClassName = sClassName;
+
+},
+
+
+
+// Public methods
+
+
+
+/**
+* @method initEvents
+* @description Initializes the custom events for the menu.
+*/
+initEvents: function() {
+
+	YAHOO.widget.Menu.superclass.initEvents.call(this);
+
+    // Create custom events
+
+    var EVENT_TYPES = YAHOO.widget.Menu._EVENT_TYPES;
+
+    this.mouseOverEvent = new CustomEvent(EVENT_TYPES.MOUSE_OVER, this);
+    this.mouseOutEvent = new CustomEvent(EVENT_TYPES.MOUSE_OUT, this);
+    this.mouseDownEvent = new CustomEvent(EVENT_TYPES.MOUSE_DOWN, this);
+    this.mouseUpEvent = new CustomEvent(EVENT_TYPES.MOUSE_UP, this);
+    this.clickEvent = new CustomEvent(EVENT_TYPES.CLICK, this);
+    this.keyPressEvent = new CustomEvent(EVENT_TYPES.KEY_PRESS, this);
+    this.keyDownEvent = new CustomEvent(EVENT_TYPES.KEY_DOWN, this);
+    this.keyUpEvent = new CustomEvent(EVENT_TYPES.KEY_UP, this);
+    this.focusEvent = new CustomEvent(EVENT_TYPES.FOCUS, this);
+    this.blurEvent = new CustomEvent(EVENT_TYPES.BLUR, this);
+    this.itemAddedEvent = new CustomEvent(EVENT_TYPES.ITEM_ADDED, this);
+    this.itemRemovedEvent = new CustomEvent(EVENT_TYPES.ITEM_REMOVED, this);
+
+},
+
+
+/**
+* @method getRoot
+* @description Finds the menu's root menu.
+*/
+getRoot: function() {
+
+    var oItem = this.parent;
+
+    if(oItem) {
+
+        var oParentMenu = oItem.parent;
+
+        return oParentMenu ? oParentMenu.getRoot() : this;
+
+    }
+    else {
+    
+        return this;
+    
+    }
+
+},
+
+
+/**
+* @method toString
+* @description Returns a string representing the menu.
+* @return {String}
+*/
+toString: function() {
+
+    return ("Menu " + this.id);
+
+},
+
+
+/**
+* @method setItemGroupTitle
+* @description Sets the title of a group of menu items.
+* @param {String} p_sGroupTitle String specifying the title of the group.
+* @param {Number} p_nGroupIndex Optional. Number specifying the group to which
+* the title belongs.
+*/
+setItemGroupTitle: function(p_sGroupTitle, p_nGroupIndex) {
+        
+    if(typeof p_sGroupTitle == "string" && p_sGroupTitle.length > 0) {
+
+        var nGroupIndex = typeof p_nGroupIndex == "number" ? p_nGroupIndex : 0,
+            oTitle = this._aGroupTitleElements[nGroupIndex];
+
+
+        if(oTitle) {
+
+            oTitle.innerHTML = p_sGroupTitle;
+            
+        }
+        else {
+
+            oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME);
+                    
+            oTitle.innerHTML = p_sGroupTitle;
+
+            this._aGroupTitleElements[nGroupIndex] = oTitle;
+
+        }
+
+
+        var i = this._aGroupTitleElements.length - 1,
+            nFirstIndex;
+
+        do {
+
+            if(this._aGroupTitleElements[i]) {
+
+                Dom.removeClass(this._aGroupTitleElements[i], "first-of-type");
+
+                nFirstIndex = i;
+
+            }
+
+        }
+        while(i--);
+
+
+        if(nFirstIndex !== null) {
+
+            Dom.addClass(
+                this._aGroupTitleElements[nFirstIndex], 
+                "first-of-type"
+            );
+
+        }
+
+    }
+
+},
+
+
+
+/**
+* @method addItem
+* @description Appends an item to the menu.
+* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
+* instance to be added to the menu.
+* @param {String} p_oItem String specifying the text of the item to be added 
+* to the menu.
+* @param {Object} p_oItem Object literal containing a set of menu item 
+* configuration properties.
+* @param {Number} p_nGroupIndex Optional. Number indicating the group to
+* which the item belongs.
+* @return {YAHOO.widget.MenuItem}
+*/
+addItem: function(p_oItem, p_nGroupIndex) {
+
+    if(p_oItem) {
+
+        return this._addItemToGroup(p_nGroupIndex, p_oItem);
+        
+    }
+
+},
+
+
+/**
+* @method addItems
+* @description Adds an array of items to the menu.
+* @param {Array} p_aItems Array of items to be added to the menu.  The array 
+* can contain strings specifying the text for each item to be created, object
+* literals specifying each of the menu item configuration properties, 
+* or MenuItem instances.
+* @param {Number} p_nGroupIndex Optional. Number specifying the group to 
+* which the items belongs.
+* @return {Array}
+*/
+addItems: function(p_aItems, p_nGroupIndex) {
+
+    if(Lang.isArray(p_aItems)) {
+
+        var nItems = p_aItems.length,
+            aItems = [],
+            oItem;
+
+
+        for(var i=0; i<nItems; i++) {
+
+            oItem = p_aItems[i];
+
+            if(oItem) {
+
+                if(Lang.isArray(oItem)) {
+    
+                    aItems[aItems.length] = this.addItems(oItem, i);
+    
+                }
+                else {
+    
+                    aItems[aItems.length] = 
+                        this._addItemToGroup(p_nGroupIndex, oItem);
+                
+                }
+
+            }
+    
+        }
+
+
+        if(aItems.length) {
+        
+            return aItems;
+        
+        }
+
+    }
+
+},
+
+
+/**
+* @method insertItem
+* @description Inserts an item into the menu at the specified index.
+* @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem 
+* instance to be added to the menu.
+* @param {String} p_oItem String specifying the text of the item to be added 
+* to the menu.
+* @param {Object} p_oItem Object literal containing a set of menu item 
+* configuration properties.
+* @param {Number} p_nItemIndex Number indicating the ordinal position at which
+* the item should be added.
+* @param {Number} p_nGroupIndex Optional. Number indicating the group to which 
+* the item belongs.
+* @return {YAHOO.widget.MenuItem}
+*/
+insertItem: function(p_oItem, p_nItemIndex, p_nGroupIndex) {
+    
+    if(p_oItem) {
+
+        return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex);
+
+    }
+
+},
+
+
+/**
+* @method removeItem
+* @description Removes the specified item from the menu.
+* @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem 
+* instance to be removed from the menu.
+* @param {Number} p_oObject Number specifying the index of the item 
+* to be removed.
+* @param {Number} p_nGroupIndex Optional. Number specifying the group to 
+* which the item belongs.
+* @return {YAHOO.widget.MenuItem}
+*/
+removeItem: function(p_oObject, p_nGroupIndex) {
+    
+    if(typeof p_oObject != "undefined") {
+
+        var oItem;
+
+        if(p_oObject instanceof YAHOO.widget.MenuItem) {
+
+            oItem = this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject);           
+
+        }
+        else if(typeof p_oObject == "number") {
+
+            oItem = this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject);
+
+        }
+
+        if(oItem) {
+
+            oItem.destroy();
+
+
+            return oItem;
+
+        }
+
+    }
+
+},
+
+
+/**
+* @method getItems
+* @description Returns an array of all of the items in the menu.
+* @return {Array}
+*/
+getItems: function() {
+
+    var aGroups = this._aItemGroups,
+        nGroups = aGroups.length;
+
+    return (
+                (nGroups == 1) ? aGroups[0] : 
+                    (Array.prototype.concat.apply([], aGroups))
+            );
+
+},
+
+
+/**
+* @method getItemGroups
+* @description Multi-dimensional Array representing the menu items as they 
+* are grouped in the menu.
+* @return {Array}
+*/        
+getItemGroups: function() {
+
+    return this._aItemGroups;
+
+},
+
+
+/**
+* @method getItem
+* @description Returns the item at the specified index.
+* @param {Number} p_nItemIndex Number indicating the ordinal position of the 
+* item to be retrieved.
+* @param {Number} p_nGroupIndex Optional. Number indicating the group to which 
+* the item belongs.
+* @return {YAHOO.widget.MenuItem}
+*/
+getItem: function(p_nItemIndex, p_nGroupIndex) {
+    
+    if(typeof p_nItemIndex == "number") {
+
+        var aGroup = this._getItemGroup(p_nGroupIndex);
+
+        if(aGroup) {
+
+            return aGroup[p_nItemIndex];
+        
+        }
+
+    }
+    
+},
+
+
+/**
+* @method clearContent
+* @description Removes all of the content from the menu, including the menu 
+* items, group titles, header and footer.
+*/
+clearContent: function() {
+
+    var aItems = this.getItems(),
+        nItems = aItems.length,
+        oElement = this.element,
+        oBody = this.body,
+        oHeader = this.header,
+        oFooter = this.footer;
+
+
+    if(nItems > 0) {
+
+        var i = nItems - 1,
+            oItem,
+            oSubmenu;
+
+        do {
+
+            oItem = aItems[i];
+
+            if(oItem) {
+
+                oSubmenu = oItem.cfg.getProperty("submenu");
+
+                if(oSubmenu) {
+
+                    this.cfg.configChangedEvent.unsubscribe(
+                                this._onParentMenuConfigChange, 
+                                oSubmenu
+                            );
+
+                    this.renderEvent.unsubscribe(
+                                        this._onParentMenuRender, 
+                                        oSubmenu
+                                    );
+
+                }
+
+                oItem.destroy();
+
+            }
+        
+        }
+        while(i--);
+
+    }
+
+
+    if(oHeader) {
+
+        Event.purgeElement(oHeader);
+        oElement.removeChild(oHeader);
+
+    }
+    
+
+    if(oFooter) {
+
+        Event.purgeElement(oFooter);
+        oElement.removeChild(oFooter);
+    }
+
+
+    if(oBody) {
+
+        Event.purgeElement(oBody);
+
+        oBody.innerHTML = "";
+
+    }
+
+
+    this._aItemGroups = [];
+    this._aListElements = [];
+    this._aGroupTitleElements = [];
+    
+    this.cfg.setProperty("width", null);
+
+},
+
+
+/**
+* @method destroy
+* @description Removes the menu's <code>&#60;div&#62;</code> element 
+* (and accompanying child nodes) from the document.
+*/
+destroy: function() {
+
+    // Remove all DOM event listeners
+
+    Event.purgeElement(this.element);
+
+
+    // Remove Custom Event listeners
+
+    this.mouseOverEvent.unsubscribeAll();
+    this.mouseOutEvent.unsubscribeAll();
+    this.mouseDownEvent.unsubscribeAll();
+    this.mouseUpEvent.unsubscribeAll();
+    this.clickEvent.unsubscribeAll();
+    this.keyPressEvent.unsubscribeAll();
+    this.keyDownEvent.unsubscribeAll();
+    this.keyUpEvent.unsubscribeAll();
+    this.focusEvent.unsubscribeAll();
+    this.blurEvent.unsubscribeAll();
+    this.itemAddedEvent.unsubscribeAll();
+    this.itemRemovedEvent.unsubscribeAll();
+    this.cfg.unsubscribeFromConfigEvent("width", this._onWidthChange);
+    this.cfg.unsubscribeFromConfigEvent("visible", this._onVisibleChange);
+
+    if (this._hasSetWidthHandlers) {
+
+        this.itemAddedEvent.unsubscribe(this._setWidth);
+        this.itemRemovedEvent.unsubscribe(this._setWidth);
+
+        this._hasSetWidthHandlers = false;
+
+    }
+
+    YAHOO.widget.Module.textResizeEvent.unsubscribe(this._onTextResize, this);
+
+
+    // Remove all items
+
+    this.clearContent();
+
+
+    this._aItemGroups = null;
+    this._aListElements = null;
+    this._aGroupTitleElements = null;
+
+
+    // Continue with the superclass implementation of this method
+
+    YAHOO.widget.Menu.superclass.destroy.call(this);
+    
+
+},
+
+
+/**
+* @method setInitialFocus
+* @description Sets focus to the menu's first enabled item.
+*/
+setInitialFocus: function() {
+
+    var oItem = this._getFirstEnabledItem();
+    
+    if (oItem) {
+
+        oItem.focus();
+
+    }
+    
+},
+
+
+/**
+* @method setInitialSelection
+* @description Sets the "selected" configuration property of the menu's first 
+* enabled item to "true."
+*/
+setInitialSelection: function() {
+
+    var oItem = this._getFirstEnabledItem();
+    
+    if(oItem) {
+    
+        oItem.cfg.setProperty("selected", true);
+    }        
+
+},
+
+
+/**
+* @method clearActiveItem
+* @description Sets the "selected" configuration property of the menu's active
+* item to "false" and hides the item's submenu.
+* @param {Boolean} p_bBlur Boolean indicating if the menu's active item 
+* should be blurred.  
+*/
+clearActiveItem: function(p_bBlur) {
+
+    if(this.cfg.getProperty("showdelay") > 0) {
+    
+        this._cancelShowDelay();
+    
+    }
+
+
+    var oActiveItem = this.activeItem;
+
+    if(oActiveItem) {
+
+        var oConfig = oActiveItem.cfg;
+
+        if(p_bBlur) {
+
+            oActiveItem.blur();
+        
+        }
+
+        oConfig.setProperty("selected", false);
+
+        var oSubmenu = oConfig.getProperty("submenu");
+
+        if(oSubmenu) {
+
+            oSubmenu.hide();
+
+        }
+
+        this.activeItem = null;            
+
+    }
+
+},
+
+
+/**
+* @method focus
+* @description Causes the menu to receive focus and fires the "focus" event.
+*/
+focus: function() {
+
+    if (!this.hasFocus()) {
+
+        this.setInitialFocus();
+    
+    }
+
+},
+
+
+/**
+* @method blur
+* @description Causes the menu to lose focus and fires the "blur" event.
+*/    
+blur: function() {
+
+    if (this.hasFocus()) {
+    
+        var oItem = YAHOO.widget.MenuManager.getFocusedMenuItem();
+        
+        if (oItem) {
+
+            oItem.blur();
+
+        }
+
+    }
+
+},
+
+
+/**
+* @method hasFocus
+* @description Returns a boolean indicating whether or not the menu has focus.
+* @return {Boolean}
+*/
+hasFocus: function() {
+
+    return (YAHOO.widget.MenuManager.getFocusedMenu() == this.getRoot());
+
+},
+
+
+/**
+* @description Initializes the class's configurable properties which can be
+* changed using the menu's Config object ("cfg").
+* @method initDefaultConfig
+*/
+initDefaultConfig: function() {
+
+    YAHOO.widget.Menu.superclass.initDefaultConfig.call(this);
+
+    var oConfig = this.cfg,
+        DEFAULT_CONFIG = YAHOO.widget.Menu._DEFAULT_CONFIG;
+
+	// Add configuration attributes
+
+    /*
+        Change the default value for the "visible" configuration 
+        property to "false" by re-adding the property.
+    */
+
+    /**
+    * @config visible
+    * @description Boolean indicating whether or not the menu is visible.  If 
+    * the menu's "position" configuration property is set to "dynamic" (the 
+    * default), this property toggles the menu's <code>&#60;div&#62;</code> 
+    * element's "visibility" style property between "visible" (true) or 
+    * "hidden" (false).  If the menu's "position" configuration property is 
+    * set to "static" this property toggles the menu's 
+    * <code>&#60;div&#62;</code> element's "display" style property 
+    * between "block" (true) or "none" (false).
+    * @default false
+    * @type Boolean
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.VISIBLE.key, 
+        {
+            handler: this.configVisible, 
+            value: DEFAULT_CONFIG.VISIBLE.value, 
+            validator: DEFAULT_CONFIG.VISIBLE.validator
+         }
+     );
+
+
+    /*
+        Change the default value for the "constraintoviewport" configuration 
+        property to "true" by re-adding the property.
+    */
+
+    /**
+    * @config constraintoviewport
+    * @description Boolean indicating if the menu will try to remain inside 
+    * the boundaries of the size of viewport.
+    * @default true
+    * @type Boolean
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, 
+        {
+            handler: this.configConstrainToViewport, 
+            value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value, 
+            validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator, 
+            supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes 
+        } 
+    );
+
+
+    /**
+    * @config position
+    * @description String indicating how a menu should be positioned on the 
+    * screen.  Possible values are "static" and "dynamic."  Static menus are 
+    * visible by default and reside in the normal flow of the document 
+    * (CSS position: static).  Dynamic menus are hidden by default, reside 
+    * out of the normal flow of the document (CSS position: absolute), and 
+    * can overlay other elements on the screen.
+    * @default dynamic
+    * @type String
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.POSITION.key, 
+        {
+            handler: this.configPosition,
+            value: DEFAULT_CONFIG.POSITION.value, 
+            validator: DEFAULT_CONFIG.POSITION.validator,
+            supercedes: DEFAULT_CONFIG.POSITION.supercedes
+        }
+    );
+
+
+    /**
+    * @config submenualignment
+    * @description Array defining how submenus should be aligned to their 
+    * parent menu item. The format is: [itemCorner, submenuCorner]. By default
+    * a submenu's top left corner is aligned to its parent menu item's top 
+    * right corner.
+    * @default ["tl","tr"]
+    * @type Array
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.SUBMENU_ALIGNMENT.key, 
+        { 
+            value: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.value 
+        }
+    );
+
+
+    /**
+    * @config autosubmenudisplay
+    * @description Boolean indicating if submenus are automatically made 
+    * visible when the user mouses over the menu's items.
+    * @default true
+    * @type Boolean
+    */
+	oConfig.addProperty(
+	   DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.key, 
+	   { 
+	       value: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.value, 
+	       validator: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.validator
+       } 
+    );
+
+
+    /**
+    * @config showdelay
+    * @description Number indicating the time (in milliseconds) that should 
+    * expire before a submenu is made visible when the user mouses over 
+    * the menu's items.
+    * @default 250
+    * @type Number
+    */
+	oConfig.addProperty(
+	   DEFAULT_CONFIG.SHOW_DELAY.key, 
+	   { 
+	       value: DEFAULT_CONFIG.SHOW_DELAY.value, 
+	       validator: DEFAULT_CONFIG.SHOW_DELAY.validator
+       } 
+    );
+
+
+    /**
+    * @config hidedelay
+    * @description Number indicating the time (in milliseconds) that should 
+    * expire before the menu is hidden.
+    * @default 0
+    * @type Number
+    */
+	oConfig.addProperty(
+	   DEFAULT_CONFIG.HIDE_DELAY.key, 
+	   { 
+	       handler: this.configHideDelay,
+	       value: DEFAULT_CONFIG.HIDE_DELAY.value, 
+	       validator: DEFAULT_CONFIG.HIDE_DELAY.validator, 
+	       suppressEvent: DEFAULT_CONFIG.HIDE_DELAY.suppressEvent
+       } 
+    );
+
+
+    /**
+    * @config submenuhidedelay
+    * @description Number indicating the time (in milliseconds) that should 
+    * expire before a submenu is hidden when the user mouses out of a menu item 
+    * heading in the direction of a submenu.  The value must be greater than or 
+    * equal to the value specified for the "showdelay" configuration property.
+    * @default 250
+    * @type Number
+    */
+	oConfig.addProperty(
+	   DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.key, 
+	   { 
+	       value: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.value, 
+	       validator: DEFAULT_CONFIG.SUBMENU_HIDE_DELAY.validator
+       } 
+    );
+
+
+    /**
+    * @config clicktohide
+    * @description Boolean indicating if the menu will automatically be 
+    * hidden if the user clicks outside of it.
+    * @default true
+    * @type Boolean
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.CLICK_TO_HIDE.key,
+        {
+            value: DEFAULT_CONFIG.CLICK_TO_HIDE.value,
+            validator: DEFAULT_CONFIG.CLICK_TO_HIDE.validator
+        }
+    );
+
+
+	/**
+	* @config container
+	* @description HTML element reference or string specifying the id 
+	* attribute of the HTML element that the menu's markup should be 
+	* rendered into.
+	* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+	* level-one-html.html#ID-58190037">HTMLElement</a>|String
+	* @default document.body
+	*/
+	oConfig.addProperty(
+	   DEFAULT_CONFIG.CONTAINER.key, 
+	   { 
+	       handler: this.configContainer,
+	       value: document.body
+       } 
+   );
+
+
+    /**
+    * @config maxheight
+    * @description Defines the maximum height (in pixels) for a menu before the
+    * contents of the body are scrolled.
+    * @default 0
+    * @type Number
+    */
+    oConfig.addProperty(
+       DEFAULT_CONFIG.MAX_HEIGHT.key, 
+       {
+            handler: this.configMaxHeight,
+            value: DEFAULT_CONFIG.MAX_HEIGHT.value,
+            validator: DEFAULT_CONFIG.MAX_HEIGHT.validator
+       } 
+    );
+
+
+    /**
+    * @config classname
+    * @description CSS class to be applied to the menu's root 
+    * <code>&#60;div&#62;</code> element.  The specified class(es) are 
+    * appended in addition to the default class as specified by the menu's
+    * CSS_CLASS_NAME constant.
+    * @default null
+    * @type String
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.CLASS_NAME.key, 
+        { 
+            handler: this.configClassName,
+            value: DEFAULT_CONFIG.CLASS_NAME.value, 
+            validator: DEFAULT_CONFIG.CLASS_NAME.validator
+        }
+    );
+
+}
+
+}); // END YAHOO.lang.extend
+
+})();
+
+
+
+(function() {
+
+var Dom = YAHOO.util.Dom,
+    Module = YAHOO.widget.Module,
+    Menu = YAHOO.widget.Menu,
+    CustomEvent = YAHOO.util.CustomEvent,
+    Lang = YAHOO.lang;
+
+/**
+* Creates an item for a menu.
+* 
+* @param {String} p_oObject String specifying the text of the menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying 
+* the <code>&#60;li&#62;</code> element of the menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 
+* specifying the <code>&#60;optgroup&#62;</code> element of the menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object 
+* specifying the <code>&#60;option&#62;</code> element of the menu item.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu item. See configuration class documentation 
+* for more details.
+* @class MenuItem
+* @constructor
+*/
+YAHOO.widget.MenuItem = function(p_oObject, p_oConfig) {
+
+    if(p_oObject) {
+
+        if(p_oConfig) {
+    
+            this.parent = p_oConfig.parent;
+            this.value = p_oConfig.value;
+            this.id = p_oConfig.id;
+
+        }
+
+        this.init(p_oObject, p_oConfig);
+
+    }
+
+};
+
+
+/**
+* Constant representing the name of the MenuItem's events
+* @property YAHOO.widget.MenuItem._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.MenuItem._EVENT_TYPES = {
+
+    "MOUSE_OVER": "mouseover",
+    "MOUSE_OUT": "mouseout",
+    "MOUSE_DOWN": "mousedown",
+    "MOUSE_UP": "mouseup",
+    "CLICK": "click",
+    "KEY_PRESS": "keypress",
+    "KEY_DOWN": "keydown",
+    "KEY_UP": "keyup",
+    "ITEM_ADDED": "itemAdded",
+    "ITEM_REMOVED": "itemRemoved",
+    "FOCUS": "focus",
+    "BLUR": "blur",
+    "DESTROY": "destroy"
+
+};
+
+
+/**
+* Constant representing the MenuItem's configuration properties
+* @property YAHOO.widget.MenuItem._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.MenuItem._DEFAULT_CONFIG = {
+
+    "TEXT": { 
+        key: "text", 
+        value: "", 
+        validator: Lang.isString, 
+        suppressEvent: true 
+    }, 
+
+    "HELP_TEXT": { 
+        key: "helptext" 
+    },
+
+    "URL": { 
+        key: "url", 
+        value: "#", 
+        suppressEvent: true 
+    }, 
+
+    "TARGET": { 
+        key: "target", 
+        suppressEvent: true 
+    }, 
+
+    "EMPHASIS": { 
+        key: "emphasis", 
+        value: false, 
+        validator: Lang.isBoolean, 
+        suppressEvent: true 
+    }, 
+
+    "STRONG_EMPHASIS": { 
+        key: "strongemphasis", 
+        value: false, 
+        validator: Lang.isBoolean, 
+        suppressEvent: true 
+    },
+
+    "CHECKED": { 
+        key: "checked", 
+        value: false, 
+        validator: Lang.isBoolean, 
+        suppressEvent: true, 
+        supercedes:["disabled"]
+    }, 
+
+    "DISABLED": { 
+        key: "disabled", 
+        value: false, 
+        validator: Lang.isBoolean, 
+        suppressEvent: true
+    },
+
+    "SELECTED": { 
+        key: "selected", 
+        value: false, 
+        validator: Lang.isBoolean, 
+        suppressEvent: true
+    },
+
+    "SUBMENU": { 
+        key: "submenu"
+    },
+
+    "ONCLICK": { 
+        key: "onclick"
+    },
+
+    "CLASS_NAME": { 
+        key: "classname", 
+        value: null, 
+        validator: Lang.isString
+    }
+
+};
+
+
+YAHOO.widget.MenuItem.prototype = {
+
+    // Constants
+
+
+    /**
+    * @property COLLAPSED_SUBMENU_INDICATOR_TEXT
+    * @description String representing the text for the <code>&#60;em&#62;</code>
+    * element used for the submenu arrow indicator.
+    * @default "Submenu collapsed.  Click to expand submenu."
+    * @final
+    * @type String
+    */
+    COLLAPSED_SUBMENU_INDICATOR_TEXT: 
+        "Submenu collapsed.  Click to expand submenu.",
+
+
+    /**
+    * @property EXPANDED_SUBMENU_INDICATOR_TEXT
+    * @description String representing the text for the submenu arrow indicator 
+    * element (<code>&#60;em&#62;</code>) when the submenu is visible.
+    * @default "Submenu expanded.  Click to collapse submenu."
+    * @final
+    * @type String
+    */
+    EXPANDED_SUBMENU_INDICATOR_TEXT: 
+        "Submenu expanded.  Click to collapse submenu.",
+
+
+    /**
+    * @property DISABLED_SUBMENU_INDICATOR_TEXT
+    * @description String representing the text for the submenu arrow indicator 
+    * element (<code>&#60;em&#62;</code>) when the menu item is disabled.
+    * @default "Submenu collapsed.  (Item disabled.)."
+    * @final
+    * @type String
+    */
+    DISABLED_SUBMENU_INDICATOR_TEXT: "Submenu collapsed.  (Item disabled.)",
+
+
+    /**
+    * @property CHECKED_TEXT
+    * @description String representing the text to be used for the checked 
+    * indicator element (<code>&#60;em&#62;</code>).
+    * @default "Checked."
+    * @final
+    * @type String
+    */
+    CHECKED_TEXT: "Menu item checked.",
+    
+    
+    /**
+    * @property DISABLED_CHECKED_TEXT
+    * @description String representing the text to be used for the checked 
+    * indicator element (<code>&#60;em&#62;</code>) when the menu item 
+    * is disabled.
+    * @default "Checked. (Item disabled.)"
+    * @final
+    * @type String
+    */
+    DISABLED_CHECKED_TEXT: "Checked. (Item disabled.)",
+
+
+    /**
+    * @property CSS_CLASS_NAME
+    * @description String representing the CSS class(es) to be applied to the 
+    * <code>&#60;li&#62;</code> element of the menu item.
+    * @default "yuimenuitem"
+    * @final
+    * @type String
+    */
+    CSS_CLASS_NAME: "yuimenuitem",
+
+
+    /**
+    * @property SUBMENU_TYPE
+    * @description Object representing the type of menu to instantiate and 
+    * add when parsing the child nodes of the menu item's source HTML element.
+    * @final
+    * @type YAHOO.widget.Menu
+    */
+    SUBMENU_TYPE: null,
+
+
+
+    // Private member variables
+    
+
+    /**
+    * @property _oAnchor
+    * @description Object reference to the menu item's 
+    * <code>&#60;a&#62;</code> element.
+    * @default null 
+    * @private
+    * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-48250443">HTMLAnchorElement</a>
+    */
+    _oAnchor: null,
+    
+
+    /**
+    * @property _oText
+    * @description Object reference to the menu item's text node.
+    * @default null
+    * @private
+    * @type TextNode
+    */
+    _oText: null,
+    
+    
+    /**
+    * @property _oHelpTextEM
+    * @description Object reference to the menu item's help text 
+    * <code>&#60;em&#62;</code> element.
+    * @default null
+    * @private
+    * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-58190037">HTMLElement</a>
+    */
+    _oHelpTextEM: null,
+    
+    
+    /**
+    * @property _oSubmenu
+    * @description Object reference to the menu item's submenu.
+    * @default null
+    * @private
+    * @type YAHOO.widget.Menu
+    */
+    _oSubmenu: null,
+    
+
+    /**
+    * @property _oCheckedIndicator
+    * @description Object reference to the menu item's checkmark image.
+    * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>
+    * @private
+    * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>
+    */
+    _oCheckedIndicator: null,
+
+
+    /** 
+    * @property _oOnclickAttributeValue
+    * @description Object reference to the menu item's current value for the 
+    * "onclick" configuration attribute.
+    * @default null
+    * @private
+    * @type Object
+    */
+    _oOnclickAttributeValue: null,
+
+
+    /**
+    * @property _sClassName
+    * @description The current value of the "classname" configuration attribute.
+    * @default null
+    * @private
+    * @type String
+    */
+    _sClassName: null,
+
+
+
+    // Public properties
+
+
+	/**
+    * @property constructor
+	* @description Object reference to the menu item's constructor function.
+    * @default YAHOO.widget.MenuItem
+	* @type YAHOO.widget.MenuItem
+	*/
+	constructor: YAHOO.widget.MenuItem,
+
+
+    /**
+    * @property index
+    * @description Number indicating the ordinal position of the menu item in 
+    * its group.
+    * @default null
+    * @type Number
+    */
+    index: null,
+
+
+    /**
+    * @property groupIndex
+    * @description Number indicating the index of the group to which the menu 
+    * item belongs.
+    * @default null
+    * @type Number
+    */
+    groupIndex: null,
+
+
+    /**
+    * @property parent
+    * @description Object reference to the menu item's parent menu.
+    * @default null
+    * @type YAHOO.widget.Menu
+    */
+    parent: null,
+
+
+    /**
+    * @property element
+    * @description Object reference to the menu item's 
+    * <code>&#60;li&#62;</code> element.
+    * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level
+    * -one-html.html#ID-74680021">HTMLLIElement</a>
+    * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-74680021">HTMLLIElement</a>
+    */
+    element: null,
+
+
+    /**
+    * @property srcElement
+    * @description Object reference to the HTML element (either 
+    * <code>&#60;li&#62;</code>, <code>&#60;optgroup&#62;</code> or 
+    * <code>&#60;option&#62;</code>) used create the menu item.
+    * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.
+    * w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"
+    * >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
+    * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
+    * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3.
+    * org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247">
+    * HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
+    * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
+    */
+    srcElement: null,
+
+
+    /**
+    * @property value
+    * @description Object reference to the menu item's value.
+    * @default null
+    * @type Object
+    */
+    value: null,
+
+
+    /**
+    * @property submenuIndicator
+    * @description Object reference to the <code>&#60;em&#62;</code> element 
+    * used to create the submenu indicator for the menu item.
+    * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>
+    * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>
+    */
+    submenuIndicator: null,
+
+
+	/**
+    * @property browser
+	* @description String representing the browser.
+	* @type String
+	*/
+	browser: Module.prototype.browser,
+
+
+    /**
+    * @property id
+    * @description Id of the menu item's root <code>&#60;li&#62;</code> 
+    * element.  This property should be set via the constructor using the 
+    * configuration object literal.  If an id is not specified, then one will 
+    * be created using the "generateId" method of the Dom utility.
+    * @default null
+    * @type String
+    */
+    id: null,
+
+
+
+    // Events
+
+
+    /**
+    * @event destroyEvent
+    * @description Fires when the menu item's <code>&#60;li&#62;</code> 
+    * element is removed from its parent <code>&#60;ul&#62;</code> element.
+    * @type YAHOO.util.CustomEvent
+    */
+    destroyEvent: null,
+
+
+    /**
+    * @event mouseOverEvent
+    * @description Fires when the mouse has entered the menu item.  Passes 
+    * back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    mouseOverEvent: null,
+
+
+    /**
+    * @event mouseOutEvent
+    * @description Fires when the mouse has left the menu item.  Passes back 
+    * the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    mouseOutEvent: null,
+
+
+    /**
+    * @event mouseDownEvent
+    * @description Fires when the user mouses down on the menu item.  Passes 
+    * back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    mouseDownEvent: null,
+
+
+    /**
+    * @event mouseUpEvent
+    * @description Fires when the user releases a mouse button while the mouse 
+    * is over the menu item.  Passes back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    mouseUpEvent: null,
+
+
+    /**
+    * @event clickEvent
+    * @description Fires when the user clicks the on the menu item.  Passes 
+    * back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    clickEvent: null,
+
+
+    /**
+    * @event keyPressEvent
+    * @description Fires when the user presses an alphanumeric key when the 
+    * menu item has focus.  Passes back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    keyPressEvent: null,
+
+
+    /**
+    * @event keyDownEvent
+    * @description Fires when the user presses a key when the menu item has 
+    * focus.  Passes back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    keyDownEvent: null,
+
+
+    /**
+    * @event keyUpEvent
+    * @description Fires when the user releases a key when the menu item has 
+    * focus.  Passes back the DOM Event object as an argument.
+    * @type YAHOO.util.CustomEvent
+    */
+    keyUpEvent: null,
+
+
+    /**
+    * @event focusEvent
+    * @description Fires when the menu item receives focus.
+    * @type YAHOO.util.CustomEvent
+    */
+    focusEvent: null,
+
+
+    /**
+    * @event blurEvent
+    * @description Fires when the menu item loses the input focus.
+    * @type YAHOO.util.CustomEvent
+    */
+    blurEvent: null,
+
+
+    /**
+    * @method init
+    * @description The MenuItem class's initialization method. This method is 
+    * automatically called by the constructor, and sets up all DOM references 
+    * for pre-existing markup, and creates required markup if it is not 
+    * already present.
+    * @param {String} p_oObject String specifying the text of the menu item.
+    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying 
+    * the <code>&#60;li&#62;</code> element of the menu item.
+    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 
+    * specifying the <code>&#60;optgroup&#62;</code> element of the menu item.
+    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+    * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object 
+    * specifying the <code>&#60;option&#62;</code> element of the menu item.
+    * @param {Object} p_oConfig Optional. Object literal specifying the 
+    * configuration for the menu item. See configuration class documentation 
+    * for more details.
+    */
+    init: function(p_oObject, p_oConfig) {
+
+
+        if(!this.SUBMENU_TYPE) {
+    
+            this.SUBMENU_TYPE = Menu;
+    
+        }
+
+
+        // Create the config object
+
+        this.cfg = new YAHOO.util.Config(this);
+
+        this.initDefaultConfig();
+
+        var oConfig = this.cfg;
+
+
+        if(Lang.isString(p_oObject)) {
+
+            this._createRootNodeStructure();
+
+            oConfig.setProperty("text", p_oObject);
+
+        }
+        else if(this._checkDOMNode(p_oObject)) {
+
+            switch(p_oObject.tagName.toUpperCase()) {
+
+                case "OPTION":
+
+                    this._createRootNodeStructure();
+
+                    oConfig.setProperty("text", p_oObject.text);
+
+                    this.srcElement = p_oObject;
+
+                break;
+
+                case "OPTGROUP":
+
+                    this._createRootNodeStructure();
+
+                    oConfig.setProperty("text", p_oObject.label);
+
+                    this.srcElement = p_oObject;
+
+                    this._initSubTree();
+
+                break;
+
+                case "LI":
+
+                    // Get the anchor node (if it exists)
+
+                    var oAnchor = this._getFirstElement(p_oObject, "A"),
+                        sURL = "#",
+                        sTarget,
+                        sText;
+
+
+                    // Capture the "text" and/or the "URL"
+
+                    if(oAnchor) {
+
+                        sURL = oAnchor.getAttribute("href");
+                        sTarget = oAnchor.getAttribute("target");
+
+                        if(oAnchor.innerText) {
+                
+                            sText = oAnchor.innerText;
+                
+                        }
+                        else {
+                
+                            var oRange = oAnchor.ownerDocument.createRange();
+                
+                            oRange.selectNodeContents(oAnchor);
+                
+                            sText = oRange.toString();             
+                
+                        }
+
+                    }
+                    else {
+
+                        var oText = p_oObject.firstChild;
+
+                        sText = oText.nodeValue;
+
+                        oAnchor = document.createElement("a");
+                        
+                        oAnchor.setAttribute("href", sURL);
+
+                        p_oObject.replaceChild(oAnchor, oText);
+                        
+                        oAnchor.appendChild(oText);
+
+                    }
+
+
+                    this.srcElement = p_oObject;
+                    this.element = p_oObject;
+                    this._oAnchor = oAnchor;
+    
+
+                    // Check if emphasis has been applied to the MenuItem
+
+                    var oEmphasisNode = this._getFirstElement(oAnchor),
+                        bEmphasis = false,
+                        bStrongEmphasis = false;
+
+                    if(oEmphasisNode) {
+
+                        // Set a reference to the text node 
+
+                        this._oText = oEmphasisNode.firstChild;
+
+                        switch(oEmphasisNode.tagName.toUpperCase()) {
+
+                            case "EM":
+
+                                bEmphasis = true;
+
+                            break;
+
+                            case "STRONG":
+
+                                bStrongEmphasis = true;
+
+                            break;
+
+                        }
+
+                    }
+                    else {
+
+                        // Set a reference to the text node 
+
+                        this._oText = oAnchor.firstChild;
+
+                    }
+
+
+                    /*
+                        Set these properties silently to sync up the 
+                        configuration object without making changes to the 
+                        element's DOM
+                    */ 
+
+                    oConfig.setProperty("text", sText, true);
+                    oConfig.setProperty("url", sURL, true);
+                    oConfig.setProperty("target", sTarget, true);
+                    oConfig.setProperty("emphasis", bEmphasis, true);
+                    oConfig.setProperty(
+                        "strongemphasis", 
+                        bStrongEmphasis, 
+                        true
+                    );
+
+                    this._initSubTree();
+
+                break;
+
+            }            
+
+        }
+
+
+        if(this.element) {
+
+            var sId = this.element.id;
+
+            if(!sId) {
+
+                sId = this.id || Dom.generateId();
+
+                this.element.id = sId;
+
+            }
+
+            this.id = sId;
+
+
+            Dom.addClass(this.element, this.CSS_CLASS_NAME);
+
+
+            // Create custom events
+
+            var EVENT_TYPES = YAHOO.widget.MenuItem._EVENT_TYPES;
+
+            this.mouseOverEvent = new CustomEvent(EVENT_TYPES.MOUSE_OVER, this);
+            this.mouseOutEvent = new CustomEvent(EVENT_TYPES.MOUSE_OUT, this);
+            this.mouseDownEvent = new CustomEvent(EVENT_TYPES.MOUSE_DOWN, this);
+            this.mouseUpEvent = new CustomEvent(EVENT_TYPES.MOUSE_UP, this);
+            this.clickEvent = new CustomEvent(EVENT_TYPES.CLICK, this);
+            this.keyPressEvent = new CustomEvent(EVENT_TYPES.KEY_PRESS, this);
+            this.keyDownEvent = new CustomEvent(EVENT_TYPES.KEY_DOWN, this);
+            this.keyUpEvent = new CustomEvent(EVENT_TYPES.KEY_UP, this);
+            this.focusEvent = new CustomEvent(EVENT_TYPES.FOCUS, this);
+            this.blurEvent = new CustomEvent(EVENT_TYPES.BLUR, this);
+            this.destroyEvent = new CustomEvent(EVENT_TYPES.DESTROY, this);
+
+            if(p_oConfig) {
+    
+                oConfig.applyConfig(p_oConfig);
+    
+            }        
+
+            oConfig.fireQueue();
+
+        }
+
+    },
+
+
+
+    // Private methods
+
+
+    /**
+    * @method _getFirstElement
+    * @description Returns an HTML element's first HTML element node.
+    * @private
+    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object 
+    * reference specifying the element to be evaluated.
+    * @param {String} p_sTagName Optional. String specifying the tagname of 
+    * the element to be retrieved.
+    * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>}
+    */
+    _getFirstElement: function(p_oElement, p_sTagName) {
+    
+        var oFirstChild = p_oElement.firstChild,
+            oElement;
+    
+        if(oFirstChild) {
+    
+            if(oFirstChild.nodeType == 1) {
+    
+                oElement = oFirstChild;
+    
+            }
+            else {
+    
+                var oNextSibling = oFirstChild.nextSibling;
+    
+                if(oNextSibling && oNextSibling.nodeType == 1) {
+                
+                    oElement = oNextSibling;
+                
+                }
+    
+            }
+    
+        }
+
+
+        if(p_sTagName) {
+
+            return (oElement && oElement.tagName.toUpperCase() == p_sTagName) ? 
+                oElement : false;
+
+        }
+        
+        return oElement;
+
+    },    
+
+
+    /**
+    * @method _checkDOMNode
+    * @description Determines if an object is an HTML element.
+    * @private
+    * @param {Object} p_oObject Object to be evaluated.
+    * @return {Boolean}
+    */
+    _checkDOMNode: function(p_oObject) {
+
+        return (p_oObject && p_oObject.tagName);
+
+    },
+
+
+    /**
+    * @method _createRootNodeStructure
+    * @description Creates the core DOM structure for the menu item.
+    * @private
+    */
+    _createRootNodeStructure: function () {
+
+        var oTemplate = YAHOO.widget.MenuItem._MenuItemTemplate;
+
+        if(!oTemplate) {
+
+            oTemplate = document.createElement("li");
+            oTemplate.innerHTML = "<a href=\"#\">s</a>";
+
+            YAHOO.widget.MenuItem._MenuItemTemplate = oTemplate;
+
+        }
+
+        this.element = oTemplate.cloneNode(true);
+        this._oAnchor = this.element.firstChild;
+        this._oText = this._oAnchor.firstChild;
+
+        this.element.appendChild(this._oAnchor);
+
+    },
+
+
+    /**
+    * @method _initSubTree
+    * @description Iterates the source element's childNodes collection and uses 
+    * the child nodes to instantiate other menus.
+    * @private
+    */
+    _initSubTree: function() {
+
+        var oSrcEl = this.srcElement,
+            oConfig = this.cfg;
+
+
+        if(oSrcEl.childNodes.length > 0) {
+
+            if(
+                this.parent.lazyLoad && 
+                this.parent.srcElement && 
+                this.parent.srcElement.tagName.toUpperCase() == "SELECT"
+            ) {
+
+                oConfig.setProperty(
+                        "submenu", 
+                        { id: Dom.generateId(), itemdata: oSrcEl.childNodes }
+                    );
+
+            }
+            else {
+
+                var oNode = oSrcEl.firstChild,
+                    aOptions = [];
+    
+                do {
+    
+                    if(oNode && oNode.tagName) {
+    
+                        switch(oNode.tagName.toUpperCase()) {
+                
+                            case "DIV":
+                
+                                oConfig.setProperty("submenu", oNode);
+                
+                            break;
+         
+                            case "OPTION":
+        
+                                aOptions[aOptions.length] = oNode;
+        
+                            break;
+               
+                        }
+                    
+                    }
+                
+                }        
+                while((oNode = oNode.nextSibling));
+    
+    
+                var nOptions = aOptions.length;
+    
+                if(nOptions > 0) {
+    
+                    var oMenu = new this.SUBMENU_TYPE(Dom.generateId());
+                    
+                    oConfig.setProperty("submenu", oMenu);
+    
+                    for(var n=0; n<nOptions; n++) {
+        
+                        oMenu.addItem((new oMenu.ITEM_TYPE(aOptions[n])));
+        
+                    }
+        
+                }
+            
+            }
+
+        }
+
+    },
+
+
+
+    // Event handlers for configuration properties
+
+
+    /**
+    * @method configText
+    * @description Event handler for when the "text" configuration property of 
+    * the menu item changes.
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */
+    configText: function(p_sType, p_aArgs, p_oItem) {
+
+        var sText = p_aArgs[0];
+
+
+        if(this._oText) {
+
+            this._oText.nodeValue = sText;
+
+        }
+
+    },
+
+
+    /**
+    * @method configHelpText
+    * @description Event handler for when the "helptext" configuration property 
+    * of the menu item changes.
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configHelpText: function(p_sType, p_aArgs, p_oItem) {
+
+        var me = this,
+            oHelpText = p_aArgs[0],
+            oEl = this.element,
+            oConfig = this.cfg,
+            aNodes = [oEl, this._oAnchor],
+            oSubmenuIndicator = this.submenuIndicator;
+
+
+        function initHelpText() {
+
+            Dom.addClass(aNodes, "hashelptext");
+
+            if(oConfig.getProperty("disabled")) {
+
+                oConfig.refireEvent("disabled");
+
+            }
+
+            if(oConfig.getProperty("selected")) {
+
+                oConfig.refireEvent("selected");
+
+            }                
+
+        }
+
+
+        function removeHelpText() {
+
+            Dom.removeClass(aNodes, "hashelptext");
+
+            oEl.removeChild(me._oHelpTextEM);
+            me._oHelpTextEM = null;
+
+        }
+
+
+        if(this._checkDOMNode(oHelpText)) {
+
+            oHelpText.className = "helptext";
+
+            if(this._oHelpTextEM) {
+            
+                this._oHelpTextEM.parentNode.replaceChild(
+                    oHelpText, 
+                    this._oHelpTextEM
+                );
+
+            }
+            else {
+
+                this._oHelpTextEM = oHelpText;
+
+                oEl.insertBefore(this._oHelpTextEM, oSubmenuIndicator);
+
+            }
+
+            initHelpText();
+
+        }
+        else if(Lang.isString(oHelpText)) {
+
+            if(oHelpText.length === 0) {
+
+                removeHelpText();
+
+            }
+            else {
+
+                if(!this._oHelpTextEM) {
+
+                    this._oHelpTextEM = document.createElement("em");
+                    this._oHelpTextEM.className = "helptext";
+
+                    oEl.insertBefore(this._oHelpTextEM, oSubmenuIndicator);
+
+                }
+
+                this._oHelpTextEM.innerHTML = oHelpText;
+
+                initHelpText();
+
+            }
+
+        }
+        else if(!oHelpText && this._oHelpTextEM) {
+
+            removeHelpText();
+
+        }
+
+    },
+
+
+    /**
+    * @method configURL
+    * @description Event handler for when the "url" configuration property of 
+    * the menu item changes.
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configURL: function(p_sType, p_aArgs, p_oItem) {
+
+        var sURL = p_aArgs[0];
+
+        if(!sURL) {
+
+            sURL = "#";
+
+        }
+
+        this._oAnchor.setAttribute("href", sURL);
+
+    },
+
+
+    /**
+    * @method configTarget
+    * @description Event handler for when the "target" configuration property 
+    * of the menu item changes.  
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configTarget: function(p_sType, p_aArgs, p_oItem) {
+
+        var sTarget = p_aArgs[0],
+            oAnchor = this._oAnchor;
+
+        if(sTarget && sTarget.length > 0) {
+
+            oAnchor.setAttribute("target", sTarget);
+
+        }
+        else {
+
+            oAnchor.removeAttribute("target");
+        
+        }
+
+    },
+
+
+    /**
+    * @method configEmphasis
+    * @description Event handler for when the "emphasis" configuration property
+    * of the menu item changes.  
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configEmphasis: function(p_sType, p_aArgs, p_oItem) {
+
+        var bEmphasis = p_aArgs[0],
+            oAnchor = this._oAnchor,
+            oText = this._oText,
+            oConfig = this.cfg,
+            oEM;
+
+
+        if(bEmphasis && oConfig.getProperty("strongemphasis")) {
+
+            oConfig.setProperty("strongemphasis", false);
+
+        }
+
+
+        if(oAnchor) {
+
+            if(bEmphasis) {
+
+                oEM = document.createElement("em");
+                oEM.appendChild(oText);
+
+                oAnchor.appendChild(oEM);
+
+            }
+            else {
+
+                oEM = this._getFirstElement(oAnchor, "EM");
+
+                if(oEM) {
+
+                    oAnchor.removeChild(oEM);
+                    oAnchor.appendChild(oText);
+
+                }
+
+            }
+
+        }
+
+    },
+
+
+    /**
+    * @method configStrongEmphasis
+    * @description Event handler for when the "strongemphasis" configuration 
+    * property of the menu item changes. 
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configStrongEmphasis: function(p_sType, p_aArgs, p_oItem) {
+
+        var bStrongEmphasis = p_aArgs[0],
+            oAnchor = this._oAnchor,
+            oText = this._oText,
+            oConfig = this.cfg,
+            oStrong;
+
+        if(bStrongEmphasis && oConfig.getProperty("emphasis")) {
+
+            oConfig.setProperty("emphasis", false);
+
+        }
+
+        if(oAnchor) {
+
+            if(bStrongEmphasis) {
+
+                oStrong = document.createElement("strong");
+                oStrong.appendChild(oText);
+
+                oAnchor.appendChild(oStrong);
+
+            }
+            else {
+
+                oStrong = this._getFirstElement(oAnchor, "STRONG");
+
+                if(oStrong) {
+
+                    oAnchor.removeChild(oStrong);
+                    oAnchor.appendChild(oText);
+
+                }
+
+            }
+
+        }
+
+    },
+
+
+    /**
+    * @method configChecked
+    * @description Event handler for when the "checked" configuration property 
+    * of the menu item changes. 
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configChecked: function(p_sType, p_aArgs, p_oItem) {
+    
+        var bChecked = p_aArgs[0],
+            oEl = this.element,
+            oConfig = this.cfg,
+            oEM;
+
+
+        if(bChecked) {
+
+            var oTemplate = YAHOO.widget.MenuItem._CheckedIndicatorTemplate;
+
+            if(!oTemplate) {
+
+                oTemplate = document.createElement("em");
+                oTemplate.innerHTML = this.CHECKED_TEXT;
+                oTemplate.className = "checkedindicator";
+
+                YAHOO.widget.MenuItem._CheckedIndicatorTemplate = oTemplate;
+
+            }
+
+            oEM = oTemplate.cloneNode(true);
+
+            var oSubmenu = this.cfg.getProperty("submenu");
+
+            if(oSubmenu && oSubmenu.element) {
+
+                oEl.insertBefore(oEM, oSubmenu.element);
+
+            }
+            else {
+
+                oEl.appendChild(oEM);
+
+            }
+
+
+            Dom.addClass(oEl, "checked");
+
+            this._oCheckedIndicator = oEM;
+
+            if(oConfig.getProperty("disabled")) {
+
+                oConfig.refireEvent("disabled");
+
+            }
+
+            if(oConfig.getProperty("selected")) {
+
+                oConfig.refireEvent("selected");
+
+            }
+        
+        }
+        else {
+
+            oEM = this._oCheckedIndicator;
+
+            Dom.removeClass(oEl, "checked");
+
+            if(oEM) {
+
+                oEl.removeChild(oEM);
+
+            }
+
+            this._oCheckedIndicator = null;
+        
+        }
+
+    },
+
+
+
+    /**
+    * @method configDisabled
+    * @description Event handler for when the "disabled" configuration property 
+    * of the menu item changes. 
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configDisabled: function(p_sType, p_aArgs, p_oItem) {
+
+        var bDisabled = p_aArgs[0],
+            oConfig = this.cfg,
+            oAnchor = this._oAnchor,
+            aNodes = [this.element, oAnchor],
+            oHelpText = this._oHelpTextEM,
+            oCheckedIndicator = this._oCheckedIndicator,
+            oSubmenuIndicator = this.submenuIndicator,
+            i = 1;
+
+
+        if(oHelpText) {
+
+            i++;
+            aNodes[i] = oHelpText;
+
+        }
+
+
+        if(oCheckedIndicator) {
+            
+            oCheckedIndicator.firstChild.nodeValue = bDisabled ? 
+                this.DISABLED_CHECKED_TEXT : 
+                this.CHECKED_TEXT;
+
+            i++;
+            aNodes[i] = oCheckedIndicator;
+            
+        }    
+
+
+        if(oSubmenuIndicator) {
+
+            oSubmenuIndicator.firstChild.nodeValue = bDisabled ? 
+                this.DISABLED_SUBMENU_INDICATOR_TEXT : 
+                this.COLLAPSED_SUBMENU_INDICATOR_TEXT;
+
+            i++;
+            aNodes[i] = oSubmenuIndicator;
+        
+        }
+
+
+        if(bDisabled) {
+
+            if(oConfig.getProperty("selected")) {
+
+                oConfig.setProperty("selected", false);
+
+            }
+
+            oAnchor.removeAttribute("href");
+
+            Dom.addClass(aNodes, "disabled");
+
+        }
+        else {
+
+            oAnchor.setAttribute("href", oConfig.getProperty("url"));
+
+            Dom.removeClass(aNodes, "disabled");
+
+        }
+
+    },
+
+
+    /**
+    * @method configSelected
+    * @description Event handler for when the "selected" configuration property 
+    * of the menu item changes. 
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */    
+    configSelected: function(p_sType, p_aArgs, p_oItem) {
+
+        if(!this.cfg.getProperty("disabled")) {
+
+            var bSelected = p_aArgs[0],
+                oHelpText = this._oHelpTextEM,
+                oSubmenuIndicator = this.submenuIndicator,
+                oCheckedIndicator = this._oCheckedIndicator,
+                aNodes = [this.element, this._oAnchor],
+                i = 1;
+
+
+            if(oHelpText) {
+    
+                i++;
+                aNodes[i] = oHelpText;
+    
+            }
+            
+
+            if(oSubmenuIndicator) {
+
+                i++;
+                aNodes[i] = oSubmenuIndicator;
+
+            }
+
+
+            if(oCheckedIndicator) {
+
+                i++;
+                aNodes[i] = oCheckedIndicator;
+            
+            }
+
+
+            if(bSelected) {
+    
+                Dom.addClass(aNodes, "selected");
+    
+            }
+            else {
+    
+                Dom.removeClass(aNodes, "selected");
+    
+            }
+
+        }
+
+    },
+
+
+    /**
+    * @method configSubmenu
+    * @description Event handler for when the "submenu" configuration property 
+    * of the menu item changes. 
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */
+    configSubmenu: function(p_sType, p_aArgs, p_oItem) {
+
+        var oEl = this.element,
+            oSubmenu = p_aArgs[0],
+            oSubmenuIndicator = this.submenuIndicator,
+            oConfig = this.cfg,
+            aNodes = [this.element, this._oAnchor],
+            bLazyLoad = this.parent && this.parent.lazyLoad,
+            oMenu;
+
+
+        if(oSubmenu) {
+
+            if(oSubmenu instanceof Menu) {
+
+                oMenu = oSubmenu;
+                oMenu.parent = this;
+                oMenu.lazyLoad = bLazyLoad;
+
+            }
+            else if(
+                typeof oSubmenu == "object" && 
+                oSubmenu.id && 
+                !oSubmenu.nodeType
+            ) {
+
+                var sSubmenuId = oSubmenu.id,
+                    oSubmenuConfig = oSubmenu;
+
+                oSubmenuConfig.lazyload = bLazyLoad;
+                oSubmenuConfig.parent = this;
+
+                oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig);
+
+
+                // Set the value of the property to the Menu instance
+                
+                this.cfg.setProperty("submenu", oMenu, true);
+
+            }
+            else {
+
+                oMenu = new this.SUBMENU_TYPE(
+                                oSubmenu,
+                                { lazyload: bLazyLoad, parent: this }                
+                            );
+
+
+                // Set the value of the property to the Menu instance
+                
+                this.cfg.setProperty("submenu", oMenu, true);
+
+            }
+
+
+            if(oMenu) {
+
+                this._oSubmenu = oMenu;
+
+
+                if(!oSubmenuIndicator) { 
+
+                    var oTemplate = 
+                            YAHOO.widget.MenuItem._oSubmenuIndicatorTemplate;
+
+                    if(!oTemplate) {
+                   
+                        oTemplate = document.createElement("em");
+                        oTemplate.innerHTML =  
+                            this.COLLAPSED_SUBMENU_INDICATOR_TEXT;
+                        oTemplate.className = "submenuindicator";
+                        
+                        YAHOO.widget.MenuItem._oSubmenuIndicatorTemplate = 
+                            oTemplate;
+
+                    }
+
+
+                    oSubmenuIndicator = oTemplate.cloneNode(true);
+
+
+                    if(oMenu.element.parentNode == oEl) {
+
+                        if(this.browser == "opera") {
+
+                            oEl.appendChild(oSubmenuIndicator);
+                            
+                            oMenu.renderEvent.subscribe(function() {
+
+                                oSubmenuIndicator.parentNode.insertBefore(
+                                                            oSubmenuIndicator, 
+                                                            oMenu.element
+                                                        );
+                            
+                            });
+                
+                        }
+                        else {
+
+                            oEl.insertBefore(oSubmenuIndicator, oMenu.element);
+                        
+                        }
+                
+                    }
+                    else {
+
+                        oEl.appendChild(oSubmenuIndicator);
+                    
+                    }
+
+                    this.submenuIndicator = oSubmenuIndicator;
+
+                }
+
+
+                Dom.addClass(aNodes, "hassubmenu");
+
+
+                if(oConfig.getProperty("disabled")) {
+
+                    oConfig.refireEvent("disabled");
+
+                }
+
+                if(oConfig.getProperty("selected")) {
+
+                    oConfig.refireEvent("selected");
+
+                }                
+            
+            }
+
+        }
+        else {
+
+            Dom.removeClass(aNodes, "hassubmenu");
+
+            if(oSubmenuIndicator) {
+
+                oEl.removeChild(oSubmenuIndicator);
+
+            }
+
+            if(this._oSubmenu) {
+
+                this._oSubmenu.destroy();
+
+            }
+
+        }
+
+    },
+
+
+    /**
+    * @method configOnClick
+    * @description Event handler for when the "onclick" configuration property 
+    * of the menu item changes. 
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */
+    configOnClick: function(p_sType, p_aArgs, p_oItem) {
+
+        var oObject = p_aArgs[0];
+
+        /*
+            Remove any existing listeners if a "click" event handler has 
+            already been specified.
+        */
+
+        if(
+            this._oOnclickAttributeValue && 
+            (this._oOnclickAttributeValue != oObject)
+        ) {
+
+            this.clickEvent.unsubscribe(
+                                this._oOnclickAttributeValue.fn, 
+                                this._oOnclickAttributeValue.obj
+                            );
+
+            this._oOnclickAttributeValue = null;
+
+        }
+
+
+        if(
+            !this._oOnclickAttributeValue && 
+            typeof oObject == "object" && 
+            typeof oObject.fn == "function"
+        ) {
+
+            this.clickEvent.subscribe(
+                    oObject.fn, 
+                    (oObject.obj || this), 
+                    oObject.scope
+                );
+
+            this._oOnclickAttributeValue = oObject;
+
+        }
+    
+    },
+
+
+    /**
+    * @method configClassName
+    * @description Event handler for when the "classname" configuration 
+    * property of a menu item changes.
+    * @param {String} p_sType String representing the name of the event that 
+    * was fired.
+    * @param {Array} p_aArgs Array of arguments sent when the event was fired.
+    * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
+    * that fired the event.
+    */
+    configClassName: function(p_sType, p_aArgs, p_oItem) {
+    
+        var sClassName = p_aArgs[0];
+    
+        if(this._sClassName) {
+    
+            Dom.removeClass(this.element, this._sClassName);
+    
+        }
+    
+        Dom.addClass(this.element, sClassName);
+        this._sClassName = sClassName;
+    
+    },
+
+
+
+    // Public methods
+
+
+	/**
+    * @method initDefaultConfig
+	* @description Initializes an item's configurable properties.
+	*/
+	initDefaultConfig : function() {
+
+        var oConfig = this.cfg,
+            DEFAULT_CONFIG = YAHOO.widget.MenuItem._DEFAULT_CONFIG;
+
+
+        // Define the configuration attributes
+
+        /**
+        * @config text
+        * @description String specifying the text label for the menu item.  
+        * When building a menu from existing HTML the value of this property
+        * will be interpreted from the menu's markup.
+        * @default ""
+        * @type String
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.TEXT.key, 
+            { 
+                handler: this.configText, 
+                value: DEFAULT_CONFIG.TEXT.value, 
+                validator: DEFAULT_CONFIG.TEXT.validator, 
+                suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent 
+            }
+        );
+        
+
+        /**
+        * @config helptext
+        * @description String specifying additional instructional text to 
+        * accompany the text for the nenu item.
+        * @default null
+        * @type String|<a href="http://www.w3.org/TR/
+        * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
+        * HTMLElement</a>
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.HELP_TEXT.key,
+            { handler: this.configHelpText }
+        );
+
+
+        /**
+        * @config url
+        * @description String specifying the URL for the menu item's anchor's 
+        * "href" attribute.  When building a menu from existing HTML the value 
+        * of this property will be interpreted from the menu's markup.
+        * @default "#"
+        * @type String
+        */        
+        oConfig.addProperty(
+            DEFAULT_CONFIG.URL.key, 
+            {
+                handler: this.configURL, 
+                value: DEFAULT_CONFIG.URL.value, 
+                suppressEvent: DEFAULT_CONFIG.URL.suppressEvent
+            }
+        );
+
+
+        /**
+        * @config target
+        * @description String specifying the value for the "target" attribute 
+        * of the menu item's anchor element. <strong>Specifying a target will 
+        * require the user to click directly on the menu item's anchor node in
+        * order to cause the browser to navigate to the specified URL.</strong> 
+        * When building a menu from existing HTML the value of this property 
+        * will be interpreted from the menu's markup.
+        * @default null
+        * @type String
+        */        
+        oConfig.addProperty(
+            DEFAULT_CONFIG.TARGET.key, 
+            {
+                handler: this.configTarget, 
+                suppressEvent: DEFAULT_CONFIG.TARGET.suppressEvent
+            }
+        );
+
+
+        /**
+        * @config emphasis
+        * @description Boolean indicating if the text of the menu item will be 
+        * rendered with emphasis.  When building a menu from existing HTML the 
+        * value of this property will be interpreted from the menu's markup.
+        * @default false
+        * @type Boolean
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.EMPHASIS.key, 
+            { 
+                handler: this.configEmphasis, 
+                value: DEFAULT_CONFIG.EMPHASIS.value, 
+                validator: DEFAULT_CONFIG.EMPHASIS.validator, 
+                suppressEvent: DEFAULT_CONFIG.EMPHASIS.suppressEvent 
+            }
+        );
+
+
+        /**
+        * @config strongemphasis
+        * @description Boolean indicating if the text of the menu item will be 
+        * rendered with strong emphasis.  When building a menu from existing 
+        * HTML the value of this property will be interpreted from the
+        * menu's markup.
+        * @default false
+        * @type Boolean
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.STRONG_EMPHASIS.key,
+            {
+                handler: this.configStrongEmphasis,
+                value: DEFAULT_CONFIG.STRONG_EMPHASIS.value,
+                validator: DEFAULT_CONFIG.STRONG_EMPHASIS.validator,
+                suppressEvent: DEFAULT_CONFIG.STRONG_EMPHASIS.suppressEvent
+            }
+        );
+
+
+        /**
+        * @config checked
+        * @description Boolean indicating if the menu item should be rendered 
+        * with a checkmark.
+        * @default false
+        * @type Boolean
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.CHECKED.key, 
+            {
+                handler: this.configChecked, 
+                value: DEFAULT_CONFIG.CHECKED.value, 
+                validator: DEFAULT_CONFIG.CHECKED.validator, 
+                suppressEvent: DEFAULT_CONFIG.CHECKED.suppressEvent,
+                supercedes: DEFAULT_CONFIG.CHECKED.supercedes
+            } 
+        );
+
+
+        /**
+        * @config disabled
+        * @description Boolean indicating if the menu item should be disabled.  
+        * (Disabled menu items are  dimmed and will not respond to user input 
+        * or fire events.)
+        * @default false
+        * @type Boolean
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.DISABLED.key,
+            {
+                handler: this.configDisabled,
+                value: DEFAULT_CONFIG.DISABLED.value,
+                validator: DEFAULT_CONFIG.DISABLED.validator,
+                suppressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent
+            }
+        );
+
+
+        /**
+        * @config selected
+        * @description Boolean indicating if the menu item should 
+        * be highlighted.
+        * @default false
+        * @type Boolean
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.SELECTED.key,
+            {
+                handler: this.configSelected,
+                value: DEFAULT_CONFIG.SELECTED.value,
+                validator: DEFAULT_CONFIG.SELECTED.validator,
+                suppressEvent: DEFAULT_CONFIG.SELECTED.suppressEvent
+            }
+        );
+
+
+        /**
+        * @config submenu
+        * @description Object specifying the submenu to be appended to the 
+        * menu item.  The value can be one of the following: <ul><li>Object 
+        * specifying a Menu instance.</li><li>Object literal specifying the
+        * menu to be created.  Format: <code>{ id: [menu id], itemdata: 
+        * [<a href="YAHOO.widget.Menu.html#itemData">array of values for 
+        * items</a>] }</code>.</li><li>String specifying the id attribute 
+        * of the <code>&#60;div&#62;</code> element of the menu.</li><li>
+        * Object specifying the <code>&#60;div&#62;</code> element of the 
+        * menu.</li></ul>
+        * @default null
+        * @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/
+        * WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
+        * HTMLElement</a>
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.SUBMENU.key, 
+            { handler: this.configSubmenu }
+        );
+
+
+        /**
+        * @config onclick
+        * @description Object literal representing the code to be executed when 
+        * the button is clicked.  Format:<br> <code> {<br> 
+        * <strong>fn:</strong> Function,   &#47;&#47; The handler to call when 
+        * the event fires.<br> <strong>obj:</strong> Object, &#47;&#47; An 
+        * object to  pass back to the handler.<br> <strong>scope:</strong> 
+        * Object &#47;&#47; The object to use for the scope of the handler.
+        * <br> } </code>
+        * @type Object
+        * @default null
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.ONCLICK.key, 
+            { handler: this.configOnClick }
+        );
+
+
+        /**
+        * @config classname
+        * @description CSS class to be applied to the menu item's root 
+        * <code>&#60;li&#62;</code> element.  The specified class(es) are 
+        * appended in addition to the default class as specified by the menu 
+        * item's CSS_CLASS_NAME constant.
+        * @default null
+        * @type String
+        */
+        oConfig.addProperty(
+            DEFAULT_CONFIG.CLASS_NAME.key, 
+            { 
+                handler: this.configClassName,
+                value: DEFAULT_CONFIG.CLASS_NAME.value, 
+                validator: DEFAULT_CONFIG.CLASS_NAME.validator
+            }
+        );
+
+	},
+
+
+    /**
+    * @method getNextEnabledSibling
+    * @description Finds the menu item's next enabled sibling.
+    * @return YAHOO.widget.MenuItem
+    */
+    getNextEnabledSibling: function() {
+
+        if(this.parent instanceof Menu) {
+
+            var nGroupIndex = this.groupIndex;
+
+            function getNextArrayItem(p_aArray, p_nStartIndex) {
+    
+                return p_aArray[p_nStartIndex] || 
+                    getNextArrayItem(p_aArray, (p_nStartIndex+1));
+    
+            }
+    
+    
+            var aItemGroups = this.parent.getItemGroups(),
+                oNextItem;
+    
+    
+            if(this.index < (aItemGroups[nGroupIndex].length - 1)) {
+    
+                oNextItem = getNextArrayItem(
+                        aItemGroups[nGroupIndex], 
+                        (this.index+1)
+                    );
+    
+            }
+            else {
+    
+                var nNextGroupIndex;
+    
+                if(nGroupIndex < (aItemGroups.length - 1)) {
+    
+                    nNextGroupIndex = nGroupIndex + 1;
+    
+                }
+                else {
+    
+                    nNextGroupIndex = 0;
+    
+                }
+    
+                var aNextGroup = getNextArrayItem(aItemGroups, nNextGroupIndex);
+    
+                // Retrieve the first menu item in the next group
+    
+                oNextItem = getNextArrayItem(aNextGroup, 0);
+    
+            }
+    
+            return (
+                oNextItem.cfg.getProperty("disabled") || 
+                oNextItem.element.style.display == "none"
+            ) ? 
+            oNextItem.getNextEnabledSibling() : oNextItem;
+
+        }
+
+    },
+
+
+    /**
+    * @method getPreviousEnabledSibling
+    * @description Finds the menu item's previous enabled sibling.
+    * @return {YAHOO.widget.MenuItem}
+    */
+    getPreviousEnabledSibling: function() {
+
+       if(this.parent instanceof Menu) {
+
+            var nGroupIndex = this.groupIndex;
+
+            function getPreviousArrayItem(p_aArray, p_nStartIndex) {
+    
+                return p_aArray[p_nStartIndex] || 
+                    getPreviousArrayItem(p_aArray, (p_nStartIndex-1));
+    
+            }
+
+            function getFirstItemIndex(p_aArray, p_nStartIndex) {
+    
+                return p_aArray[p_nStartIndex] ? 
+                    p_nStartIndex : 
+                    getFirstItemIndex(p_aArray, (p_nStartIndex+1));
+    
+            }
+    
+            var aItemGroups = this.parent.getItemGroups(),
+                oPreviousItem;
+    
+            if(
+                this.index > getFirstItemIndex(aItemGroups[nGroupIndex], 0)
+            ) {
+    
+                oPreviousItem = 
+                    getPreviousArrayItem(
+                        aItemGroups[nGroupIndex], 
+                        (this.index-1)
+                    );
+    
+            }
+            else {
+    
+                var nPreviousGroupIndex;
+    
+                if(nGroupIndex > getFirstItemIndex(aItemGroups, 0)) {
+    
+                    nPreviousGroupIndex = nGroupIndex - 1;
+    
+                }
+                else {
+    
+                    nPreviousGroupIndex = aItemGroups.length - 1;
+    
+                }
+    
+                var aPreviousGroup = 
+                        getPreviousArrayItem(aItemGroups, nPreviousGroupIndex);
+    
+                oPreviousItem = 
+                    getPreviousArrayItem(
+                        aPreviousGroup, 
+                        (aPreviousGroup.length - 1)
+                    );
+    
+            }
+
+            return (
+                oPreviousItem.cfg.getProperty("disabled") || 
+                oPreviousItem.element.style.display == "none"
+            ) ? 
+            oPreviousItem.getPreviousEnabledSibling() : oPreviousItem;
+
+        }
+
+    },
+
+
+    /**
+    * @method focus
+    * @description Causes the menu item to receive the focus and fires the 
+    * focus event.
+    */
+    focus: function() {
+
+        var oParent = this.parent,
+            oAnchor = this._oAnchor,
+            oActiveItem = oParent.activeItem,
+            me = this;
+
+
+        function setFocus() {
+
+            try {
+
+                if (
+                    (me.browser == "ie" || me.browser == "ie7") && 
+                    !document.hasFocus()
+                ) {
+                
+                    return;
+                
+                }
+
+                oAnchor.focus();
+
+            }
+            catch(e) {
+            
+            }
+
+        }
+
+
+        if(
+            !this.cfg.getProperty("disabled") && 
+            oParent && 
+            oParent.cfg.getProperty("visible") && 
+            this.element.style.display != "none"
+        ) {
+
+            if(oActiveItem) {
+
+                oActiveItem.blur();
+
+            }
+
+
+            /*
+                Setting focus via a timer fixes a race condition in Firefox, IE 
+                and Opera where the browser viewport jumps as it trys to 
+                position and focus the menu.
+            */
+
+            window.setTimeout(setFocus, 0);
+            
+            this.focusEvent.fire();
+
+        }
+
+    },
+
+
+    /**
+    * @method blur
+    * @description Causes the menu item to lose focus and fires the 
+    * blur event.
+    */    
+    blur: function() {
+
+        var oParent = this.parent;
+
+        if(
+            !this.cfg.getProperty("disabled") && 
+            oParent && 
+            Dom.getStyle(oParent.element, "visibility") == "visible"
+        ) {
+
+            this._oAnchor.blur();
+
+            this.blurEvent.fire();
+
+        }
+
+    },
+
+
+    /**
+    * @method hasFocus
+    * @description Returns a boolean indicating whether or not the menu item
+    * has focus.
+    * @return {Boolean}
+    */
+    hasFocus: function() {
+    
+        return (YAHOO.widget.MenuManager.getFocusedMenuItem() == this);
+    
+    },
+
+
+	/**
+    * @method destroy
+	* @description Removes the menu item's <code>&#60;li&#62;</code> element 
+	* from its parent <code>&#60;ul&#62;</code> element.
+	*/
+    destroy: function() {
+
+        var oEl = this.element;
+
+        if(oEl) {
+
+
+            // If the item has a submenu, destroy it first
+
+            var oSubmenu = this.cfg.getProperty("submenu");
+
+            if(oSubmenu) {
+            
+                oSubmenu.destroy();
+            
+            }
+
+
+            // Remove CustomEvent listeners
+    
+            this.mouseOverEvent.unsubscribeAll();
+            this.mouseOutEvent.unsubscribeAll();
+            this.mouseDownEvent.unsubscribeAll();
+            this.mouseUpEvent.unsubscribeAll();
+            this.clickEvent.unsubscribeAll();
+            this.keyPressEvent.unsubscribeAll();
+            this.keyDownEvent.unsubscribeAll();
+            this.keyUpEvent.unsubscribeAll();
+            this.focusEvent.unsubscribeAll();
+            this.blurEvent.unsubscribeAll();
+            this.cfg.configChangedEvent.unsubscribeAll();
+
+
+            // Remove the element from the parent node
+
+            var oParentNode = oEl.parentNode;
+
+            if(oParentNode) {
+
+                oParentNode.removeChild(oEl);
+
+                this.destroyEvent.fire();
+
+            }
+
+            this.destroyEvent.unsubscribeAll();
+
+        }
+
+    },
+
+
+    /**
+    * @method toString
+    * @description Returns a string representing the menu item.
+    * @return {String}
+    */
+    toString: function() {
+    
+        return ("MenuItem: " + this.cfg.getProperty("text"));
+    
+    }
+
+};
+
+})();
+
+
+
+/**
+* Creates a list of options or commands which are made visible in response to 
+* an HTML element's "contextmenu" event ("mousedown" for Opera).
+*
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;div&#62;</code> element of the context menu.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;select&#62;</code> element to be used as the data source for the 
+* context menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
+* html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the 
+* <code>&#60;div&#62;</code> element of the context menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
+* html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying 
+* the <code>&#60;select&#62;</code> element to be used as the data source for 
+* the context menu.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the context menu. See configuration class documentation 
+* for more details.
+* @class ContextMenu
+* @constructor
+* @extends YAHOO.widget.Menu
+* @namespace YAHOO.widget
+*/
+YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) {
+
+    YAHOO.widget.ContextMenu.superclass.constructor.call(
+            this, 
+            p_oElement,
+            p_oConfig
+        );
+
+};
+
+
+/**
+* Constant representing the name of the ContextMenu's events
+* @property YAHOO.widget.ContextMenu._EVENT_TYPES
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.ContextMenu._EVENT_TYPES = {
+
+    "TRIGGER_CONTEXT_MENU": "triggerContextMenu",
+
+    "CONTEXT_MENU": (
+                        (YAHOO.widget.Module.prototype.browser == "opera" ? 
+                            "mousedown" : "contextmenu")
+                    ),
+    "CLICK": "click"
+
+};
+
+
+/**
+* Constant representing the ContextMenu's configuration properties
+* @property YAHOO.widget.ContextMenu._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.ContextMenu._DEFAULT_CONFIG = {
+
+    "TRIGGER": { 
+        key: "trigger" 
+    }
+
+};
+
+
+YAHOO.lang.extend(YAHOO.widget.ContextMenu, YAHOO.widget.Menu, {
+
+
+
+// Private properties
+
+
+/**
+* @property _oTrigger
+* @description Object reference to the current value of the "trigger" 
+* configuration property.
+* @default null
+* @private
+* @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve
+* l-one-html.html#ID-58190037">HTMLElement</a>|Array
+*/
+_oTrigger: null,
+
+
+/**
+* @property _bCancelled
+* @description Boolean indicating if the display of the context menu should 
+* be cancelled.
+* @default false
+* @private
+* @type Boolean
+*/
+_bCancelled: false,
+
+
+
+// Public properties
+
+
+/**
+* @property contextEventTarget
+* @description Object reference for the HTML element that was the target of the
+* "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of 
+* the context menu.
+* @default null
+* @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
+* html.html#ID-58190037">HTMLElement</a>
+*/
+contextEventTarget: null,
+
+
+
+// Events
+
+
+/**
+* @event triggerContextMenuEvent
+* @description Custom Event wrapper for the "contextmenu" DOM event 
+* ("mousedown" for Opera) fired by the element(s) that trigger the display of 
+* the context menu.
+*/
+triggerContextMenuEvent: null,
+
+
+
+/**
+* @method init
+* @description The ContextMenu class's initialization method. This method is 
+* automatically called by the constructor, and sets up all DOM references for 
+* pre-existing markup, and creates required markup if it is not already present.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;div&#62;</code> element of the context menu.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;select&#62;</code> element to be used as the data source for 
+* the context menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
+* html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the 
+* <code>&#60;div&#62;</code> element of the context menu.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
+* html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying 
+* the <code>&#60;select&#62;</code> element to be used as the data source for 
+* the context menu.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the context menu. See configuration class documentation 
+* for more details.
+*/
+init: function(p_oElement, p_oConfig) {
+
+    if(!this.ITEM_TYPE) {
+
+        this.ITEM_TYPE = YAHOO.widget.ContextMenuItem;
+
+    }
+
+
+    // Call the init of the superclass (YAHOO.widget.Menu)
+
+    YAHOO.widget.ContextMenu.superclass.init.call(this, p_oElement);
+
+
+    this.beforeInitEvent.fire(YAHOO.widget.ContextMenu);
+
+
+    if(p_oConfig) {
+
+        this.cfg.applyConfig(p_oConfig, true);
+
+    }
+    
+    
+    this.initEvent.fire(YAHOO.widget.ContextMenu);
+    
+},
+
+
+/**
+* @method initEvents
+* @description Initializes the custom events for the context menu.
+*/
+initEvents: function() {
+
+	YAHOO.widget.ContextMenu.superclass.initEvents.call(this);
+
+    // Create custom events
+
+    this.triggerContextMenuEvent = 
+
+            new YAHOO.util.CustomEvent(
+                    YAHOO.widget.ContextMenu._EVENT_TYPES.TRIGGER_CONTEXT_MENU, 
+                    this
+                );
+
+},
+
+
+/**
+* @method cancel
+* @description Cancels the display of the context menu.
+*/
+cancel: function() {
+
+    this._bCancelled = true;
+
+},
+
+
+
+// Private methods
+
+
+/**
+* @method _removeEventHandlers
+* @description Removes all of the DOM event handlers from the HTML element(s) 
+* whose "context menu" event ("click" for Opera) trigger the display of 
+* the context menu.
+* @private
+*/
+_removeEventHandlers: function() {
+
+    var Event = YAHOO.util.Event,
+        oTrigger = this._oTrigger;
+
+
+    // Remove the event handlers from the trigger(s)
+
+    if (oTrigger) {
+
+        Event.removeListener(
+            oTrigger, 
+            YAHOO.widget.ContextMenu._EVENT_TYPES.CONTEXT_MENU, 
+            this._onTriggerContextMenu
+        );    
+        
+        if(this.browser == "opera") {
+        
+            Event.removeListener(
+                oTrigger, 
+                YAHOO.widget.ContextMenu._EVENT_TYPES.CLICK, 
+                this._onTriggerClick
+            );
+    
+        }
+
+    }
+
+},
+
+
+
+// Private event handlers
+
+
+/**
+* @method _onTriggerClick
+* @description "click" event handler for the HTML element(s) identified as the 
+* "trigger" for the context menu.  Used to cancel default behaviors in Opera.
+* @private
+* @param {Event} p_oEvent Object representing the DOM event object passed back 
+* by the event utility (YAHOO.util.Event).
+* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context 
+* menu that is handling the event.
+*/
+_onTriggerClick: function(p_oEvent, p_oMenu) {
+
+    if(p_oEvent.ctrlKey) {
+    
+        YAHOO.util.Event.stopEvent(p_oEvent);
+
+    }
+    
+},
+
+
+/**
+* @method _onTriggerContextMenu
+* @description "contextmenu" event handler ("mousedown" for Opera) for the HTML 
+* element(s) that trigger the display of the context menu.
+* @private
+* @param {Event} p_oEvent Object representing the DOM event object passed back 
+* by the event utility (YAHOO.util.Event).
+* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context 
+* menu that is handling the event.
+*/
+_onTriggerContextMenu: function(p_oEvent, p_oMenu) {
+
+    var Event = YAHOO.util.Event;
+
+    if(p_oEvent.type == "mousedown" && !p_oEvent.ctrlKey) {
+
+        return;
+
+    }
+
+
+    /*
+        Prevent the browser's default context menu from appearing and 
+        stop the propagation of the "contextmenu" event so that 
+        other ContextMenu instances are not displayed.
+    */
+
+    Event.stopEvent(p_oEvent);
+
+
+    // Hide any other ContextMenu instances that might be visible
+
+    YAHOO.widget.MenuManager.hideVisible();
+
+
+    this.contextEventTarget = Event.getTarget(p_oEvent);
+
+    this.triggerContextMenuEvent.fire(p_oEvent);
+
+
+    if(!this._bCancelled) {
+
+        // Position and display the context menu
+    
+        this.cfg.setProperty("xy", Event.getXY(p_oEvent));
+
+        this.show();
+
+    }
+
+    this._bCancelled = false;
+
+},
+
+
+
+// Public methods
+
+
+/**
+* @method toString
+* @description Returns a string representing the context menu.
+* @return {String}
+*/
+toString: function() {
+
+    return ("ContextMenu " + this.id);
+
+},
+
+
+/**
+* @method initDefaultConfig
+* @description Initializes the class's configurable properties which can be 
+* changed using the context menu's Config object ("cfg").
+*/
+initDefaultConfig: function() {
+
+    YAHOO.widget.ContextMenu.superclass.initDefaultConfig.call(this);
+
+    /**
+    * @config trigger
+    * @description The HTML element(s) whose "contextmenu" event ("mousedown" 
+    * for Opera) trigger the display of the context menu.  Can be a string 
+    * representing the id attribute of the HTML element, an object reference 
+    * for the HTML element, or an array of strings or HTML element references.
+    * @default null
+    * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
+    * level-one-html.html#ID-58190037">HTMLElement</a>|Array
+    */
+    this.cfg.addProperty(
+        YAHOO.widget.ContextMenu._DEFAULT_CONFIG.TRIGGER.key, 
+        { handler: this.configTrigger }
+    );
+
+},
+
+
+/**
+* @method destroy
+* @description Removes the context menu's <code>&#60;div&#62;</code> element 
+* (and accompanying child nodes) from the document.
+*/
+destroy: function() {
+
+    // Remove the DOM event handlers from the current trigger(s)
+
+    this._removeEventHandlers();
+    
+
+    // Continue with the superclass implementation of this method
+
+    YAHOO.widget.ContextMenu.superclass.destroy.call(this);
+
+},
+
+
+
+// Public event handlers for configuration properties
+
+
+/**
+* @method configTrigger
+* @description Event handler for when the value of the "trigger" configuration 
+* property changes. 
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context 
+* menu that fired the event.
+*/
+configTrigger: function(p_sType, p_aArgs, p_oMenu) {
+    
+    var Event = YAHOO.util.Event,
+        oTrigger = p_aArgs[0];
+
+    if(oTrigger) {
+
+        /*
+            If there is a current "trigger" - remove the event handlers 
+            from that element(s) before assigning new ones
+        */
+
+        if(this._oTrigger) {
+        
+            this._removeEventHandlers();
+
+        }
+
+        this._oTrigger = oTrigger;
+
+
+        /*
+            Listen for the "mousedown" event in Opera b/c it does not 
+            support the "contextmenu" event
+        */ 
+  
+        Event.on(
+            oTrigger, 
+            YAHOO.widget.ContextMenu._EVENT_TYPES.CONTEXT_MENU, 
+            this._onTriggerContextMenu,
+            this,
+            true
+        );
+
+
+        /*
+            Assign a "click" event handler to the trigger element(s) for
+            Opera to prevent default browser behaviors.
+        */
+
+        if(this.browser == "opera") {
+        
+            Event.on(
+                oTrigger, 
+                YAHOO.widget.ContextMenu._EVENT_TYPES.CLICK, 
+                this._onTriggerClick,
+                this,
+                true
+            );
+
+        }
+
+    }
+    else {
+   
+        this._removeEventHandlers();
+    
+    }
+    
+}
+
+}); // END YAHOO.lang.extend
+
+
+
+/**
+* Creates an item for a context menu.
+* 
+* @param {String} p_oObject String specifying the text of the context menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 
+* <code>&#60;li&#62;</code> element of the context menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 
+* specifying the <code>&#60;optgroup&#62;</code> element of the context 
+* menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 
+* the <code>&#60;option&#62;</code> element of the context menu item.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the context menu item. See configuration class 
+* documentation for more details.
+* @class ContextMenuItem
+* @constructor
+* @extends YAHOO.widget.MenuItem
+*/
+YAHOO.widget.ContextMenuItem = function(p_oObject, p_oConfig) {
+
+    YAHOO.widget.ContextMenuItem.superclass.constructor.call(
+        this, 
+        p_oObject, 
+        p_oConfig
+    );
+
+};
+
+YAHOO.lang.extend(YAHOO.widget.ContextMenuItem, YAHOO.widget.MenuItem, {
+
+
+/**
+* @method init
+* @description The ContextMenuItem class's initialization method. This method 
+* is automatically called by the constructor, and sets up all DOM references 
+* for pre-existing markup, and creates required markup if it is not 
+* already present.
+* @param {String} p_oObject String specifying the text of the context menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 
+* <code>&#60;li&#62;</code> element of the context menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 
+* specifying the <code>&#60;optgroup&#62;</code> element of the context 
+* menu item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 
+* the <code>&#60;option&#62;</code> element of the context menu item.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the context menu item. See configuration class 
+* documentation for more details.
+*/
+init: function(p_oObject, p_oConfig) {
+    
+    if(!this.SUBMENU_TYPE) {
+
+        this.SUBMENU_TYPE = YAHOO.widget.ContextMenu;
+
+    }
+
+
+    /* 
+        Call the init of the superclass (YAHOO.widget.MenuItem)
+        Note: We don't pass the user config in here yet 
+        because we only want it executed once, at the lowest 
+        subclass level.
+    */ 
+
+    YAHOO.widget.ContextMenuItem.superclass.init.call(this, p_oObject);
+
+    var oConfig = this.cfg;
+
+    if(p_oConfig) {
+
+        oConfig.applyConfig(p_oConfig, true);
+
+    }
+
+    oConfig.fireQueue();
+
+},
+
+
+
+// Public methods
+
+
+/**
+* @method toString
+* @description Returns a string representing the context menu item.
+* @return {String}
+*/
+toString: function() {
+
+    return ("ContextMenuItem: " + this.cfg.getProperty("text"));
+
+}
+    
+}); // END YAHOO.lang.extend
+
+
+
+/**
+* Horizontal collection of items, each of which can contain a submenu.
+* 
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;div&#62;</code> element of the menu bar.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;select&#62;</code> element to be used as the data source for the 
+* menu bar.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying 
+* the <code>&#60;div&#62;</code> element of the menu bar.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object 
+* specifying the <code>&#60;select&#62;</code> element to be used as the data 
+* source for the menu bar.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu bar. See configuration class documentation for
+* more details.
+* @class Menubar
+* @constructor
+* @extends YAHOO.widget.Menu
+* @namespace YAHOO.widget
+*/
+YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) {
+
+    YAHOO.widget.MenuBar.superclass.constructor.call(
+            this, 
+            p_oElement,
+            p_oConfig
+        );
+
+};
+
+
+/**
+* Constant representing the MenuBar's configuration properties
+* @property YAHOO.widget.MenuBar._DEFAULT_CONFIG
+* @private
+* @final
+* @type Object
+*/
+YAHOO.widget.MenuBar._DEFAULT_CONFIG = {
+
+    "POSITION": { 
+        key: "position", 
+        value: "static", 
+        validator: YAHOO.widget.Menu._checkPosition, 
+        supercedes: ["visible"] 
+    }, 
+
+    "SUBMENU_ALIGNMENT": { 
+        key: "submenualignment", 
+        value: ["tl","bl"] 
+    },
+
+    "AUTO_SUBMENU_DISPLAY": { 
+        key: "autosubmenudisplay", 
+        value: false, 
+        validator: YAHOO.lang.isBoolean 
+    }
+
+};
+
+
+
+YAHOO.lang.extend(YAHOO.widget.MenuBar, YAHOO.widget.Menu, {
+
+/**
+* @method init
+* @description The MenuBar class's initialization method. This method is 
+* automatically called by the constructor, and sets up all DOM references for 
+* pre-existing markup, and creates required markup if it is not already present.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;div&#62;</code> element of the menu bar.
+* @param {String} p_oElement String specifying the id attribute of the 
+* <code>&#60;select&#62;</code> element to be used as the data source for the 
+* menu bar.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying 
+* the <code>&#60;div&#62;</code> element of the menu bar.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object 
+* specifying the <code>&#60;select&#62;</code> element to be used as the data 
+* source for the menu bar.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu bar. See configuration class documentation for
+* more details.
+*/
+init: function(p_oElement, p_oConfig) {
+
+    if(!this.ITEM_TYPE) {
+
+        this.ITEM_TYPE = YAHOO.widget.MenuBarItem;
+
+    }
+
+
+    // Call the init of the superclass (YAHOO.widget.Menu)
+
+    YAHOO.widget.MenuBar.superclass.init.call(this, p_oElement);
+
+
+    this.beforeInitEvent.fire(YAHOO.widget.MenuBar);
+
+
+    if(p_oConfig) {
+
+        this.cfg.applyConfig(p_oConfig, true);
+
+    }
+
+    this.initEvent.fire(YAHOO.widget.MenuBar);
+
+},
+
+
+
+// Constants
+
+
+/**
+* @property CSS_CLASS_NAME
+* @description String representing the CSS class(es) to be applied to the menu 
+* bar's <code>&#60;div&#62;</code> element.
+* @default "yuimenubar"
+* @final
+* @type String
+*/
+CSS_CLASS_NAME: "yuimenubar",
+
+
+
+// Protected event handlers
+
+
+/**
+* @method _onKeyDown
+* @description "keydown" Custom Event handler for the menu bar.
+* @private
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar 
+* that fired the event.
+*/
+_onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) {
+
+    var Event = YAHOO.util.Event,
+        oEvent = p_aArgs[0],
+        oItem = p_aArgs[1],
+        oSubmenu;
+
+
+    if(oItem && !oItem.cfg.getProperty("disabled")) {
+
+        var oItemCfg = oItem.cfg;
+
+        switch(oEvent.keyCode) {
+    
+            case 37:    // Left arrow
+            case 39:    // Right arrow
+    
+                if(
+                    oItem == this.activeItem && 
+                    !oItemCfg.getProperty("selected")
+                ) {
+    
+                    oItemCfg.setProperty("selected", true);
+    
+                }
+                else {
+    
+                    var oNextItem = (oEvent.keyCode == 37) ? 
+                            oItem.getPreviousEnabledSibling() : 
+                            oItem.getNextEnabledSibling();
+            
+                    if(oNextItem) {
+    
+                        this.clearActiveItem();
+    
+                        oNextItem.cfg.setProperty("selected", true);
+    
+    
+                        if(this.cfg.getProperty("autosubmenudisplay")) {
+                        
+                            oSubmenu = oNextItem.cfg.getProperty("submenu");
+                            
+                            if(oSubmenu) {
+                        
+                                oSubmenu.show();
+                            
+                            }
+                
+                        }           
+    
+                        oNextItem.focus();
+    
+                    }
+    
+                }
+    
+                Event.preventDefault(oEvent);
+    
+            break;
+    
+            case 40:    // Down arrow
+    
+                if(this.activeItem != oItem) {
+    
+                    this.clearActiveItem();
+    
+                    oItemCfg.setProperty("selected", true);
+                    oItem.focus();
+                
+                }
+    
+                oSubmenu = oItemCfg.getProperty("submenu");
+    
+                if(oSubmenu) {
+    
+                    if(oSubmenu.cfg.getProperty("visible")) {
+    
+                        oSubmenu.setInitialSelection();
+                        oSubmenu.setInitialFocus();
+                    
+                    }
+                    else {
+    
+                        oSubmenu.show();
+                    
+                    }
+    
+                }
+    
+                Event.preventDefault(oEvent);
+    
+            break;
+    
+        }
+
+    }
+
+
+    if(oEvent.keyCode == 27 && this.activeItem) { // Esc key
+
+        oSubmenu = this.activeItem.cfg.getProperty("submenu");
+
+        if(oSubmenu && oSubmenu.cfg.getProperty("visible")) {
+        
+            oSubmenu.hide();
+            this.activeItem.focus();
+        
+        }
+        else {
+
+            this.activeItem.cfg.setProperty("selected", false);
+            this.activeItem.blur();
+    
+        }
+
+        Event.preventDefault(oEvent);
+    
+    }
+
+},
+
+
+/**
+* @method _onClick
+* @description "click" event handler for the menu bar.
+* @protected
+* @param {String} p_sType String representing the name of the event that 
+* was fired.
+* @param {Array} p_aArgs Array of arguments sent when the event was fired.
+* @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar 
+* that fired the event.
+*/
+_onClick: function(p_sType, p_aArgs, p_oMenuBar) {
+
+    YAHOO.widget.MenuBar.superclass._onClick.call(
+        this, 
+        p_sType, 
+        p_aArgs, 
+        p_oMenuBar
+    );
+
+
+    var oItem = p_aArgs[1];
+    
+    if(oItem && !oItem.cfg.getProperty("disabled")) {
+
+         var Event = YAHOO.util.Event,
+             Dom = YAHOO.util.Dom,
+    
+             oEvent = p_aArgs[0],
+             oTarget = Event.getTarget(oEvent),
+    
+             oActiveItem = this.activeItem,
+             oConfig = this.cfg;
+
+
+        // Hide any other submenus that might be visible
+    
+        if(oActiveItem && oActiveItem != oItem) {
+    
+            this.clearActiveItem();
+    
+        }
+
+    
+        oItem.cfg.setProperty("selected", true);
+    
+
+        // Show the submenu for the item
+    
+        var oSubmenu = oItem.cfg.getProperty("submenu");
+
+
+        if(oSubmenu && oTarget != oItem.submenuIndicator) {
+        
+            if(oSubmenu.cfg.getProperty("visible")) {
+            
+                oSubmenu.hide();
+            
+            }
+            else {
+            
+                oSubmenu.show();                    
+            
+            }
+        
+        }
+    
+    }
+
+},
+
+
+
+// Public methods
+
+
+/**
+* @method toString
+* @description Returns a string representing the menu bar.
+* @return {String}
+*/
+toString: function() {
+
+    return ("MenuBar " + this.id);
+
+},
+
+
+/**
+* @description Initializes the class's configurable properties which can be
+* changed using the menu bar's Config object ("cfg").
+* @method initDefaultConfig
+*/
+initDefaultConfig: function() {
+
+    YAHOO.widget.MenuBar.superclass.initDefaultConfig.call(this);
+
+    var oConfig = this.cfg,
+        DEFAULT_CONFIG = YAHOO.widget.MenuBar._DEFAULT_CONFIG;
+
+	// Add configuration properties
+
+
+    /*
+        Set the default value for the "position" configuration property
+        to "static" by re-adding the property.
+    */
+
+
+    /**
+    * @config position
+    * @description String indicating how a menu bar should be positioned on the 
+    * screen.  Possible values are "static" and "dynamic."  Static menu bars 
+    * are visible by default and reside in the normal flow of the document 
+    * (CSS position: static).  Dynamic menu bars are hidden by default, reside
+    * out of the normal flow of the document (CSS position: absolute), and can 
+    * overlay other elements on the screen.
+    * @default static
+    * @type String
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.POSITION.key, 
+        {
+            handler: this.configPosition, 
+            value: DEFAULT_CONFIG.POSITION.value, 
+            validator: DEFAULT_CONFIG.POSITION.validator,
+            supercedes: DEFAULT_CONFIG.POSITION.supercedes
+        }
+    );
+
+
+    /*
+        Set the default value for the "submenualignment" configuration property
+        to ["tl","bl"] by re-adding the property.
+    */
+
+    /**
+    * @config submenualignment
+    * @description Array defining how submenus should be aligned to their 
+    * parent menu bar item. The format is: [itemCorner, submenuCorner].
+    * @default ["tl","bl"]
+    * @type Array
+    */
+    oConfig.addProperty(
+        DEFAULT_CONFIG.SUBMENU_ALIGNMENT.key, 
+        {
+            value: DEFAULT_CONFIG.SUBMENU_ALIGNMENT.value
+        }
+    );
+
+
+    /*
+        Change the default value for the "autosubmenudisplay" configuration 
+        property to "false" by re-adding the property.
+    */
+
+    /**
+    * @config autosubmenudisplay
+    * @description Boolean indicating if submenus are automatically made 
+    * visible when the user mouses over the menu bar's items.
+    * @default false
+    * @type Boolean
+    */
+	oConfig.addProperty(
+	   DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.key, 
+	   {
+	       value: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.value, 
+	       validator: DEFAULT_CONFIG.AUTO_SUBMENU_DISPLAY.validator
+       } 
+    );
+
+}
+ 
+}); // END YAHOO.lang.extend
+
+
+
+/**
+* Creates an item for a menu bar.
+* 
+* @param {String} p_oObject String specifying the text of the menu bar item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 
+* <code>&#60;li&#62;</code> element of the menu bar item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 
+* specifying the <code>&#60;optgroup&#62;</code> element of the menu bar item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 
+* the <code>&#60;option&#62;</code> element of the menu bar item.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu bar item. See configuration class documentation 
+* for more details.
+* @class MenuBarItem
+* @constructor
+* @extends YAHOO.widget.MenuItem
+*/
+YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) {
+
+    YAHOO.widget.MenuBarItem.superclass.constructor.call(
+        this, 
+        p_oObject, 
+        p_oConfig
+    );
+
+};
+
+YAHOO.lang.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, {
+
+
+/**
+* @method init
+* @description The MenuBarItem class's initialization method. This method is 
+* automatically called by the constructor, and sets up all DOM references for 
+* pre-existing markup, and creates required markup if it is not already present.
+* @param {String} p_oObject String specifying the text of the menu bar item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the 
+* <code>&#60;li&#62;</code> element of the menu bar item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object 
+* specifying the <code>&#60;optgroup&#62;</code> element of the menu bar item.
+* @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
+* one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying 
+* the <code>&#60;option&#62;</code> element of the menu bar item.
+* @param {Object} p_oConfig Optional. Object literal specifying the 
+* configuration for the menu bar item. See configuration class documentation 
+* for more details.
+*/
+init: function(p_oObject, p_oConfig) {
+
+    if(!this.SUBMENU_TYPE) {
+
+        this.SUBMENU_TYPE = YAHOO.widget.Menu;
+
+    }
+
+
+    /* 
+        Call the init of the superclass (YAHOO.widget.MenuItem)
+        Note: We don't pass the user config in here yet 
+        because we only want it executed once, at the lowest 
+        subclass level.
+    */ 
+
+    YAHOO.widget.MenuBarItem.superclass.init.call(this, p_oObject);  
+
+
+    var oConfig = this.cfg;
+
+    if(p_oConfig) {
+
+        oConfig.applyConfig(p_oConfig, true);
+
+    }
+
+    oConfig.fireQueue();
+
+},
+
+
+
+// Constants
+
+/**
+* @property CSS_CLASS_NAME
+* @description String representing the CSS class(es) to be applied to the 
+* <code>&#60;li&#62;</code> element of the menu bar item.
+* @default "yuimenubaritem"
+* @final
+* @type String
+*/
+CSS_CLASS_NAME: "yuimenubaritem",
+
+
+
+// Public methods
+
+
+/**
+* @method toString
+* @description Returns a string representing the menu bar item.
+* @return {String}
+*/
+toString: function() {
+
+    return ("MenuBarItem: " + this.cfg.getProperty("text"));
+
+}
+    
+}); // END YAHOO.lang.extend
+YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.2.1", build: "193"});

Modified: jifty/branches/virtual-models/share/web/static/js/yui/tabview.js
==============================================================================
--- jifty/branches/virtual-models/share/web/static/js/yui/tabview.js	(original)
+++ jifty/branches/virtual-models/share/web/static/js/yui/tabview.js	Mon May  7 16:28:32 2007
@@ -1,1950 +1,1021 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.12.0
-*/
-(function() {
-
-    YAHOO.util.Lang = {
-        isArray: function(val) { // frames lose type, so test constructor string
-            if (val.constructor && val.constructor.toString().indexOf('Array') > -1) {
-                return true;
-            } else {
-                return YAHOO.util.Lang.isObject(val) && val.constructor == Array;
-            }
-        },
-
-        isBoolean: function(val) {
-            return typeof val == 'boolean';
-        },
-
-        isFunction: function(val) {
-            return typeof val == 'function';
-        },
-
-        isNull: function(val) {
-            return val === null;
-        },
-
-        isNumber: function(val) {
-            return !isNaN(val);
-        },
-
-        isObject: function(val) {
-            return typeof val == 'object' || YAHOO.util.Lang.isFunction(val);
-        },
-
-        isString: function(val) {
-            return typeof val == 'string';
-        },
-
-        isUndefined: function(val) {
-            return typeof val == 'undefined';
-        }
-    };
-})();/**
- * Provides Attribute configurations.
- * @namespace YAHOO.util
- * @class Attribute
- * @constructor
- * @param hash {Object} The intial Attribute.
- * @param {YAHOO.util.AttributeProvider} The owner of the Attribute instance.
- */
-
-YAHOO.util.Attribute = function(hash, owner) {
-    if (owner) {
-        this.owner = owner;
-        this.configure(hash, true);
-    }
-};
-
-YAHOO.util.Attribute.prototype = {
-	/**
-     * The name of the attribute.
-	 * @property name
-	 * @type String
-	 */
-    name: undefined,
-
-	/**
-     * The value of the attribute.
-	 * @property value
-	 * @type String
-	 */
-    value: null,
-
-	/**
-     * The owner of the attribute.
-	 * @property owner
-	 * @type YAHOO.util.AttributeProvider
-	 */
-    owner: null,
-
-	/**
-     * Whether or not the attribute is read only.
-	 * @property readOnly
-	 * @type Boolean
-	 */
-    readOnly: false,
-
-	/**
-     * Whether or not the attribute can only be written once.
-	 * @property writeOnce
-	 * @type Boolean
-	 */
-    writeOnce: false,
-
-	/**
-     * The attribute's initial configuration.
-     * @private
-	 * @property _initialConfig
-	 * @type Object
-	 */
-    _initialConfig: null,
-
-	/**
-     * Whether or not the attribute's value has been set.
-     * @private
-	 * @property _written
-	 * @type Boolean
-	 */
-    _written: false,
-
-	/**
-     * The method to use when setting the attribute's value.
-     * The method recieves the new value as the only argument.
-	 * @property method
-	 * @type Function
-	 */
-    method: null,
-
-	/**
-     * The validator to use when setting the attribute's value.
-	 * @property validator
-	 * @type Function
-     * @return Boolean
-	 */
-    validator: null,
-
-    /**
-     * Retrieves the current value of the attribute.
-     * @method getValue
-     * @return {any} The current value of the attribute.
-     */
-    getValue: function() {
-        return this.value;
-    },
-
-    /**
-     * Sets the value of the attribute and fires beforeChange and change events.
-     * @method setValue
-     * @param {Any} value The value to apply to the attribute.
-     * @param {Boolean} silent If true the change events will not be fired.
-     * @return {Boolean} Whether or not the value was set.
-     */
-    setValue: function(value, silent) {
-        var beforeRetVal;
-        var owner = this.owner;
-        var name = this.name;
-
-        var event = {
-            type: name,
-            prevValue: this.getValue(),
-            newValue: value
-        };
-
-        if (this.readOnly || ( this.writeOnce && this._written) ) {
-            return false; // write not allowed
-        }
-
-        if (this.validator && !this.validator.call(owner, value) ) {
-            return false; // invalid value
-        }
-
-        if (!silent) {
-            beforeRetVal = owner.fireBeforeChangeEvent(event);
-            if (beforeRetVal === false) {
-                YAHOO.log('setValue ' + name +
-                        'cancelled by beforeChange event', 'info', 'Attribute');
-                return false;
-            }
-        }
-
-        if (this.method) {
-            this.method.call(owner, value);
-        }
-
-        this.value = value;
-        this._written = true;
-
-        event.type = name;
-
-        if (!silent) {
-            this.owner.fireChangeEvent(event);
-        }
-
-        return true;
-    },
-
-    /**
-     * Allows for configuring the Attribute's properties.
-     * @method configure
-     * @param {Object} map A key-value map of Attribute properties.
-     * @param {Boolean} init Whether or not this should become the initial config.
-     */
-    configure: function(map, init) {
-        map = map || {};
-        this._written = false; // reset writeOnce
-        this._initialConfig = this._initialConfig || {};
-
-        for (var key in map) {
-            if ( key && map.hasOwnProperty(key) ) {
-                this[key] = map[key];
-                if (init) {
-                    this._initialConfig[key] = map[key];
-                }
-            }
-        }
-    },
-
-    /**
-     * Resets the value to the initial config value.
-     * @method resetValue
-     * @return {Boolean} Whether or not the value was set.
-     */
-    resetValue: function() {
-        return this.setValue(this._initialConfig.value);
-    },
-
-    /**
-     * Resets the attribute config to the initial config state.
-     * @method resetConfig
-     */
-    resetConfig: function() {
-        this.configure(this._initialConfig);
-    },
-
-    /**
-     * Resets the value to the current value.
-     * Useful when values may have gotten out of sync with actual properties.
-     * @method refresh
-     * @return {Boolean} Whether or not the value was set.
-     */
-    refresh: function(silent) {
-        this.setValue(this.value, silent);
-    }
-};(function() {
-    var Lang = YAHOO.util.Lang;
-
-    /*
-    Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-    Code licensed under the BSD License:
-    http://developer.yahoo.net/yui/license.txt
-    */
-
-    /**
-     * Provides and manages YAHOO.util.Attribute instances
-     * @namespace YAHOO.util
-     * @class AttributeProvider
-     * @uses YAHOO.util.EventProvider
-     */
-    YAHOO.util.AttributeProvider = function() {};
-
-    YAHOO.util.AttributeProvider.prototype = {
-
-        /**
-         * A key-value map of Attribute configurations
-         * @property _configs
-         * @protected (may be used by subclasses and augmentors)
-         * @private
-         * @type {Object}
-         */
-        _configs: null,
-        /**
-         * Returns the current value of the attribute.
-         * @method get
-         * @param {String} key The attribute whose value will be returned.
-         */
-        get: function(key){
-            var configs = this._configs || {};
-            var config = configs[key];
-
-            if (!config) {
-                YAHOO.log(key + ' not found', 'error', 'AttributeProvider');
-                return undefined;
-            }
-
-            return config.value;
-        },
-
-        /**
-         * Sets the value of a config.
-         * @method set
-         * @param {String} key The name of the attribute
-         * @param {Any} value The value to apply to the attribute
-         * @param {Boolean} silent Whether or not to suppress change events
-         * @return {Boolean} Whether or not the value was set.
-         */
-        set: function(key, value, silent){
-            var configs = this._configs || {};
-            var config = configs[key];
-
-            if (!config) {
-                YAHOO.log('set failed: ' + key + ' not found',
-                        'error', 'AttributeProvider');
-                return false;
-            }
-
-            return config.setValue(value, silent);
-        },
-
-        /**
-         * Returns an array of attribute names.
-         * @method getAttributeKeys
-         * @return {Array} An array of attribute names.
-         */
-        getAttributeKeys: function(){
-            var configs = this._configs;
-            var keys = [];
-            var config;
-            for (var key in configs) {
-                config = configs[key];
-                if ( configs.hasOwnProperty(key) &&
-                        !Lang.isUndefined(config) ) {
-                    keys[keys.length] = key;
-                }
-            }
-
-            return keys;
-        },
-
-        /**
-         * Sets multiple attribute values.
-         * @method setAttributes
-         * @param {Object} map  A key-value map of attributes
-         * @param {Boolean} silent Whether or not to suppress change events
-         */
-        setAttributes: function(map, silent){
-            for (var key in map) {
-                if ( map.hasOwnProperty(key) ) {
-                    this.set(key, map[key], silent);
-                }
-            }
-        },
-
-        /**
-         * Resets the specified attribute's value to its initial value.
-         * @method resetValue
-         * @param {String} key The name of the attribute
-         * @param {Boolean} silent Whether or not to suppress change events
-         * @return {Boolean} Whether or not the value was set
-         */
-        resetValue: function(key, silent){
-            var configs = this._configs || {};
-            if (configs[key]) {
-                this.set(key, configs[key]._initialConfig.value, silent);
-                return true;
-            }
-            return false;
-        },
-
-        /**
-         * Sets the attribute's value to its current value.
-         * @method refresh
-         * @param {String | Array} key The attribute(s) to refresh
-         * @param {Boolean} silent Whether or not to suppress change events
-         */
-        refresh: function(key, silent){
-            var configs = this._configs;
-
-            key = ( ( Lang.isString(key) ) ? [key] : key ) ||
-                    this.getAttributeKeys();
-
-            for (var i = 0, len = key.length; i < len; ++i) {
-                if ( // only set if there is a value and not null
-                    configs[key[i]] &&
-                    ! Lang.isUndefined(configs[key[i]].value) &&
-                    ! Lang.isNull(configs[key[i]].value) ) {
-                    configs[key[i]].refresh(silent);
-                }
-            }
-        },
-
-        /**
-         * Adds an Attribute to the AttributeProvider instance.
-         * @method register
-         * @param {String} key The attribute's name
-         * @param {Object} map A key-value map containing the
-         * attribute's properties.
-         */
-        register: function(key, map) {
-            this._configs = this._configs || {};
-
-            if (this._configs[key]) { // dont override
-                return false;
-            }
-
-            map.name = key;
-            this._configs[key] = new YAHOO.util.Attribute(map, this);
-            return true;
-        },
-
-        /**
-         * Returns the attribute's properties.
-         * @method getAttributeConfig
-         * @param {String} key The attribute's name
-         * @private
-         * @return {object} A key-value map containing all of the
-         * attribute's properties.
-         */
-        getAttributeConfig: function(key) {
-            var configs = this._configs || {};
-            var config = configs[key] || {};
-            var map = {}; // returning a copy to prevent overrides
-
-            for (key in config) {
-                if ( config.hasOwnProperty(key) ) {
-                    map[key] = config[key];
-                }
-            }
-
-            return map;
-        },
-
-        /**
-         * Sets or updates an Attribute instance's properties.
-         * @method configureAttribute
-         * @param {String} key The attribute's name.
-         * @param {Object} map A key-value map of attribute properties
-         * @param {Boolean} init Whether or not this should become the intial config.
-         */
-        configureAttribute: function(key, map, init) {
-            var configs = this._configs || {};
-
-            if (!configs[key]) {
-                YAHOO.log('unable to configure, ' + key + ' not found',
-                        'error', 'AttributeProvider');
-                return false;
-            }
-
-            configs[key].configure(map, init);
-        },
-
-        /**
-         * Resets an attribute to its intial configuration.
-         * @method resetAttributeConfig
-         * @param {String} key The attribute's name.
-         * @private
-         */
-        resetAttributeConfig: function(key){
-            var configs = this._configs || {};
-            configs[key].resetConfig();
-        },
-
-        /**
-         * Fires the attribute's beforeChange event.
-         * @method fireBeforeChangeEvent
-         * @param {String} key The attribute's name.
-         * @param {Obj} e The event object to pass to handlers.
-         */
-        fireBeforeChangeEvent: function(e) {
-            var type = 'before';
-            type += e.type.charAt(0).toUpperCase() + e.type.substr(1) + 'Change';
-            e.type = type;
-            return this.fireEvent(e.type, e);
-        },
-
-        /**
-         * Fires the attribute's change event.
-         * @method fireChangeEvent
-         * @param {String} key The attribute's name.
-         * @param {Obj} e The event object to pass to the handlers.
-         */
-        fireChangeEvent: function(e) {
-            e.type += 'Change';
-            return this.fireEvent(e.type, e);
-        }
-    };
-
-    YAHOO.augment(YAHOO.util.AttributeProvider, YAHOO.util.EventProvider);
-})();(function() {
-// internal shorthand
-var Dom = YAHOO.util.Dom,
-    Lang = YAHOO.util.Lang,
-    EventPublisher = YAHOO.util.EventPublisher,
-    AttributeProvider = YAHOO.util.AttributeProvider;
-
-/**
- * Element provides an interface to an HTMLElement's attributes and common
- * methods.  Other commonly used attributes are added as well.
- * @namespace YAHOO.util
- * @class Element
- * @uses YAHOO.util.AttributeProvider
- * @constructor
- * @param el {HTMLElement | String} The html element that
- * represents the Element.
- * @param {Object} map A key-value map of initial config names and values
- */
-YAHOO.util.Element = function(el, map) {
-    if (arguments.length) {
-        this.init(el, map);
-    }
-};
-
-YAHOO.util.Element.prototype = {
-	/**
-     * Dom events supported by the Element instance.
-	 * @property DOM_EVENTS
-	 * @type Object
-	 */
-    DOM_EVENTS: null,
-
-	/**
-     * Wrapper for HTMLElement method.
-	 * @method appendChild
-	 * @param {Boolean} deep Whether or not to do a deep clone
-	 */
-    appendChild: function(child) {
-        child = child.get ? child.get('element') : child;
-        this.get('element').appendChild(child);
-    },
-
-	/**
-     * Wrapper for HTMLElement method.
-	 * @method getElementsByTagName
-	 * @param {String} tag The tagName to collect
-	 */
-    getElementsByTagName: function(tag) {
-        return this.get('element').getElementsByTagName(tag);
-    },
-
-	/**
-     * Wrapper for HTMLElement method.
-	 * @method hasChildNodes
-	 * @return {Boolean} Whether or not the element has childNodes
-	 */
-    hasChildNodes: function() {
-        return this.get('element').hasChildNodes();
-    },
-
-	/**
-     * Wrapper for HTMLElement method.
-	 * @method insertBefore
-	 * @param {HTMLElement} element The HTMLElement to insert
-	 * @param {HTMLElement} before The HTMLElement to insert
-     * the element before.
-	 */
-    insertBefore: function(element, before) {
-        element = element.get ? element.get('element') : element;
-        before = (before && before.get) ? before.get('element') : before;
-
-        this.get('element').insertBefore(element, before);
-    },
-
-	/**
-     * Wrapper for HTMLElement method.
-	 * @method removeChild
-	 * @param {HTMLElement} child The HTMLElement to remove
-	 */
-    removeChild: function(child) {
-        child = child.get ? child.get('element') : child;
-        this.get('element').removeChild(child);
-        return true;
-    },
-
-	/**
-     * Wrapper for HTMLElement method.
-	 * @method replaceChild
-	 * @param {HTMLElement} newNode The HTMLElement to insert
-	 * @param {HTMLElement} oldNode The HTMLElement to replace
-	 */
-    replaceChild: function(newNode, oldNode) {
-        newNode = newNode.get ? newNode.get('element') : newNode;
-        oldNode = oldNode.get ? oldNode.get('element') : oldNode;
-        return this.get('element').replaceChild(newNode, oldNode);
-    },
-
-
-    /**
-     * Registers Element specific attributes.
-     * @method initAttributes
-     * @param {Object} map A key-value map of initial attribute configs
-     */
-    initAttributes: function(map) {
-        map = map || {};
-        var element = Dom.get(map.element) || null;
-
-        /**
-         * The HTMLElement the Element instance refers to.
-         * @config element
-         * @type HTMLElement
-         */
-        this.register('element', {
-            value: element,
-            readOnly: true
-         });
-    },
-
-    /**
-     * Adds a listener for the given event.  These may be DOM or
-     * customEvent listeners.  Any event that is fired via fireEvent
-     * can be listened for.  All handlers receive an event object.
-     * @method addListener
-     * @param {String} type The name of the event to listen for
-     * @param {Function} fn The handler to call when the event fires
-     * @param {Any} obj A variable to pass to the handler
-     * @param {Object} scope The object to use for the scope of the handler
-     */
-    addListener: function(type, fn, obj, scope) {
-        var el = this.get('element');
-        var scope = scope || this;
-
-        el = this.get('id') || el;
-
-        if (!this._events[type]) { // create on the fly
-            if ( this.DOM_EVENTS[type] ) {
-                YAHOO.util.Event.addListener(el, type, function(e) {
-                    if (e.srcElement && !e.target) { // supplement IE with target
-                        e.target = e.srcElement;
-                    }
-                    this.fireEvent(type, e);
-                }, obj, scope);
-            }
-
-            this.createEvent(type, this);
-            this._events[type] = true;
-        }
-
-        this.subscribe.apply(this, arguments); // notify via customEvent
-    },
-
-
-    /**
-     * Alias for addListener
-     * @method on
-     * @param {String} type The name of the event to listen for
-     * @param {Function} fn The function call when the event fires
-     * @param {Any} obj A variable to pass to the handler
-     * @param {Object} scope The object to use for the scope of the handler
-     */
-    on: function() { this.addListener.apply(this, arguments); },
-
-
-    /**
-     * Remove an event listener
-     * @method removeListener
-     * @param {String} type The name of the event to listen for
-     * @param {Function} fn The function call when the event fires
-     */
-    removeListener: function(type, fn) {
-        this.unsubscribe.apply(this, arguments);
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method addClass
-	 * @param {String} className The className to add
-	 */
-    addClass: function(className) {
-        Dom.addClass(this.get('element'), className);
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method getElementsByClassName
-	 * @param {String} className The className to collect
-	 * @param {String} tag (optional) The tag to use in
-     * conjunction with class name
-     * @return {Array} Array of HTMLElements
-	 */
-    getElementsByClassName: function(className, tag) {
-        return Dom.getElementsByClassName(className, tag,
-                this.get('element') );
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method hasClass
-	 * @param {String} className The className to add
-     * @return {Boolean} Whether or not the element has the class name
-	 */
-    hasClass: function(className) {
-        return Dom.hasClass(this.get('element'), className);
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method removeClass
-	 * @param {String} className The className to remove
-	 */
-    removeClass: function(className) {
-        return Dom.removeClass(this.get('element'), className);
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method replaceClass
-	 * @param {String} oldClassName The className to replace
-	 * @param {String} newClassName The className to add
-	 */
-    replaceClass: function(oldClassName, newClassName) {
-        return Dom.replaceClass(this.get('element'),
-                oldClassName, newClassName);
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method setStyle
-	 * @param {String} property The style property to set
-	 * @param {String} value The value to apply to the style property
-	 */
-    setStyle: function(property, value) {
-        return Dom.setStyle(this.get('element'),  property, value);
-    },
-
-	/**
-     * Wrapper for Dom method.
-	 * @method getStyle
-	 * @param {String} property The style property to retrieve
-	 * @return {String} The current value of the property
-	 */
-    getStyle: function(property) {
-        return Dom.getStyle(this.get('element'),  property);
-    },
-
-	/**
-     * Apply any queued set calls.
-	 * @method fireQueue
-	 */
-    fireQueue: function() {
-        var queue = this._queue;
-        for (var i = 0, len = queue.length; i < len; ++i) {
-            this[queue[i][0]].apply(this, queue[i][1]);
-        }
-    },
-
-	/**
-     * Appends the HTMLElement into either the supplied parentNode.
-	 * @method appendTo
-	 * @param {HTMLElement | Element} parentNode The node to append to
-	 * @param {HTMLElement | Element} before An optional node to insert before
-	 */
-    appendTo: function(parent, before) {
-        parent = (parent.get) ?  parent.get('element') : Dom.get(parent);
-
-        before = (before && before.get) ?
-                before.get('element') : Dom.get(before);
-        var element = this.get('element');
-
-        var newAddition =  !Dom.inDocument(element);
-
-        if (!element) {
-            YAHOO.log('appendTo failed: element not available',
-                    'error', 'Element');
-            return false;
-        }
-
-        if (!parent) {
-            YAHOO.log('appendTo failed: parent not available',
-                    'error', 'Element');
-            return false;
-        }
-
-        if (element.parent != parent) {
-            if (before) {
-                parent.insertBefore(element, before);
-            } else {
-                parent.appendChild(element);
-            }
-        }
-
-        YAHOO.log(element + 'appended to ' + parent);
-
-        if (!newAddition) {
-            return false; // note return; no refresh if in document
-        }
-
-        // if a new addition, refresh HTMLElement any applied attributes
-        var keys = this.getAttributeKeys();
-
-        for (var key in keys) { // only refresh HTMLElement attributes
-            if ( !Lang.isUndefined(element[key]) ) {
-                this.refresh(key);
-            }
-        }
-    },
-
-    get: function(key) {
-        var configs = this._configs || {};
-        var el = configs.element; // avoid loop due to 'element'
-        if (el && !configs[key] && !Lang.isUndefined(el.value[key]) ) {
-            return el.value[key];
-        }
-
-        return AttributeProvider.prototype.get.call(this, key);
-    },
-
-    set: function(key, value, silent) {
-        var el = this.get('element');
-        if (!el) {
-            this._queue[key] = ['set', arguments];
-            return false;
-        }
-
-        // set it on the element if not a property
-        if ( !this._configs[key] && !Lang.isUndefined(el[key]) ) {
-            _registerHTMLAttr(this, key);
-        }
-
-        return AttributeProvider.prototype.set.apply(this, arguments);
-    },
-
-    register: function(key) { // protect html attributes
-        var configs = this._configs || {};
-        var element = this.get('element') || null;
-
-        if ( element && !Lang.isUndefined(element[key]) ) {
-            YAHOO.log(key + ' is reserved for ' + element,
-                    'error', 'Element');
-            return false;
-        }
-
-        return AttributeProvider.prototype.register.apply(this, arguments);
-    },
-
-    configureAttribute: function(property, map, init) { // protect html attributes
-        if (!this._configs[property] && this._configs.element &&
-                !Lang.isUndefined(this._configs.element[property]) ) {
-            _registerHTMLAttr(this, property, map);
-            return false;
-        }
-
-        return AttributeProvider.prototype.configure.apply(this, arguments);
-    },
-
-    getAttributeKeys: function() {
-        var el = this.get('element');
-        var keys = AttributeProvider.prototype.getAttributeKeys.call(this);
-
-        //add any unconfigured element keys
-        for (var key in el) {
-            if (!this._configs[key]) {
-                keys[key] = keys[key] || el[key];
-            }
-        }
-
-        return keys;
-    },
-
-    init: function(el, attr) {
-        this._queue = this._queue || [];
-        this._events = this._events || {};
-        this._configs = this._configs || {};
-        attr = attr || {};
-        attr.element = attr.element || el || null;
-
-        this.DOM_EVENTS = {
-            'click': true,
-            'keydown': true,
-            'keypress': true,
-            'keyup': true,
-            'mousedown': true,
-            'mousemove': true,
-            'mouseout': true,
-            'mouseover': true,
-            'mouseup': true
-        };
-
-        var readyHandler = function() {
-            this.initAttributes(attr);
-
-            this.setAttributes(attr, true);
-            this.fireQueue();
-            this.fireEvent('contentReady', {
-                type: 'contentReady',
-                target: attr.element
-            });
-        };
-
-        if ( Lang.isString(el) ) {
-            _registerHTMLAttr(this, 'id', { value: el });
-            YAHOO.util.Event.onAvailable(el, function() {
-                attr.element = Dom.get(el);
-                this.fireEvent('available', {
-                    type: 'available',
-                    target: attr.element
-                });
-            }, this, true);
-
-            YAHOO.util.Event.onContentReady(el, function() {
-                readyHandler.call(this);
-            }, this, true);
-        } else {
-            readyHandler.call(this);
-        }
-    }
-};
-
-/**
- * Sets the value of the property and fires beforeChange and change events.
- * @private
- * @method _registerHTMLAttr
- * @param {YAHOO.util.Element} element The Element instance to
- * register the config to.
- * @param {String} key The name of the config to register
- * @param {Object} map A key-value map of the config's params
- */
-var _registerHTMLAttr = function(self, key, map) {
-    var el = self.get('element');
-    map = map || {};
-    map.name = key;
-    map.method = map.method || function(value) {
-        el[key] = value;
-    };
-    map.value = map.value || el[key];
-    self._configs[key] = new YAHOO.util.Attribute(map, self);
-};
-
-/**
- * Fires when the Element's HTMLElement can be retrieved by Id.
- * <p>See: <a href="#addListener">Element.addListener</a></p>
- * <p><strong>Event fields:</strong><br>
- * <code>&lt;String&gt; type</code> available<br>
- * <code>&lt;HTMLElement&gt;
- * target</code> the HTMLElement bound to this Element instance<br>
- * <p><strong>Usage:</strong><br>
- * <code>var handler = function(e) {var target = e.target};<br>
- * myTabs.addListener('available', handler);</code></p>
- * @event available
- */
-
-/**
- * Fires when the Element's HTMLElement subtree is rendered.
- * <p>See: <a href="#addListener">Element.addListener</a></p>
- * <p><strong>Event fields:</strong><br>
- * <code>&lt;String&gt; type</code> contentReady<br>
- * <code>&lt;HTMLElement&gt;
- * target</code> the HTMLElement bound to this Element instance<br>
- * <p><strong>Usage:</strong><br>
- * <code>var handler = function(e) {var target = e.target};<br>
- * myTabs.addListener('contentReady', handler);</code></p>
- * @event contentReady
- */
-
-YAHOO.augment(YAHOO.util.Element, AttributeProvider);
-})();(function() {
-    var Dom = YAHOO.util.Dom,
-        Event = YAHOO.util.Event,
-        Lang = YAHOO.util.Lang;
-
-    /**
-     * A representation of a Tab's label and content.
-     * @namespace YAHOO.widget
-     * @class Tab
-     * @extends YAHOO.util.Element
-     * @constructor
-     * @param element {HTMLElement | String} (optional) The html element that
-     * represents the TabView. An element will be created if none provided.
-     * @param {Object} properties A key map of initial properties
-     */
-    Tab = function(el, attr) {
-        attr = attr || {};
-        if (arguments.length == 1 && !Lang.isString(el) && !el.nodeName) {
-            attr = el;
-            el = attr.element;
-        }
-
-        if (!el && !attr.element) {
-            el = _createTabElement.call(this, attr);
-        }
-
-        this.loadHandler =  {
-            success: function(o) {
-                this.set('content', o.responseText);
-            },
-            failure: function(o) {
-                YAHOO.log('loading failed: ' + o.statusText,
-                        'error', 'Tab');
-            }
-        };
-
-        Tab.superclass.constructor.call(this, el, attr);
-
-        this.DOM_EVENTS = {}; // delegating to tabView
-    };
-
-    YAHOO.extend(Tab, YAHOO.util.Element);
-    var proto = Tab.prototype;
-
-    /**
-     * The default tag name for a Tab's inner element.
-     * @property LABEL_INNER_TAGNAME
-     * @type String
-     * @default "em"
-     */
-    proto.LABEL_TAGNAME = 'em';
-
-    /**
-     * The class name applied to active tabs.
-     * @property ACTIVE_CLASSNAME
-     * @type String
-     * @default "on"
-     */
-    proto.ACTIVE_CLASSNAME = 'selected';
-
-    /**
-     * The class name applied to disabled tabs.
-     * @property DISABLED_CLASSNAME
-     * @type String
-     * @default "disabled"
-     */
-    proto.DISABLED_CLASSNAME = 'disabled';
-
-    /**
-     * The class name applied to dynamic tabs while loading.
-     * @property LOADING_CLASSNAME
-     * @type String
-     * @default "disabled"
-     */
-    proto.LOADING_CLASSNAME = 'loading';
-
-    /**
-     * Provides a reference to the connection request object when data is
-     * loaded dynamically.
-     * @property dataConnection
-     * @type Object
-     */
-    proto.dataConnection = null;
-
-    /**
-     * Object containing success and failure callbacks for loading data.
-     * @property loadHandler
-     * @type object
-     */
-    proto.loadHandler = null;
-
-    /**
-     * Provides a readable name for the tab.
-     * @method toString
-     * @return String
-     */
-    proto.toString = function() {
-        var el = this.get('element');
-        var id = el.id || el.tagName;
-        return "Tab " + id;
-    };
-
-    /**
-     * Registers TabView specific properties.
-     * @method initAttributes
-     * @param {Object} attr Hash of initial attributes
-     */
-    proto.initAttributes = function(attr) {
-        attr = attr || {};
-        Tab.superclass.initAttributes.call(this, attr);
-
-        var el = this.get('element');
-
-        /**
-         * The event that triggers the tab's activation.
-         * @config activationEvent
-         * @type String
-         */
-        this.register('activationEvent', {
-            value: attr.activationEvent || 'click'
-        });
-
-        /**
-         * The element that contains the tab's label.
-         * @config labelEl
-         * @type HTMLElement
-         */
-        this.register('labelEl', {
-            value: attr.labelEl || _getlabelEl.call(this),
-            method: function(value) {
-                var current = this.get('labelEl');
-
-                if (current) {
-                    if (current == value) {
-                        return false; // already set
-                    }
-
-                    this.replaceChild(value, current);
-                } else if (el.firstChild) { // ensure label is firstChild by default
-                    this.insertBefore(value, el.firstChild);
-                } else {
-                    this.appendChild(value);
-                }
-            }
-        });
-
-        /**
-         * The tab's label text (or innerHTML).
-         * @config label
-         * @type String
-         */
-        this.register('label', {
-            value: attr.label || _getLabel.call(this),
-            method: function(value) {
-                var labelEl = this.get('labelEl');
-                if (!labelEl) { // create if needed
-                    this.set('labelEl', _createlabelEl.call(this));
-                }
-
-                _setLabel.call(this, value);
-            }
-        });
-
-        /**
-         * The HTMLElement that contains the tab's content.
-         * @config contentEl
-         * @type HTMLElement
-         */
-        this.register('contentEl', { // TODO: apply className?
-            value: attr.contentEl || document.createElement('div'),
-            method: function(value) {
-                var current = this.get('contentEl');
-
-                if (current) {
-                    if (current == value) {
-                        return false; // already set
-                    }
-                    this.replaceChild(value, current);
-                }
-            }
-        });
-
-        /**
-         * The tab's content.
-         * @config content
-         * @type String
-         */
-        this.register('content', {
-            value: attr.content, // TODO: what about existing?
-            method: function(value) {
-                this.get('contentEl').innerHTML = value;
-            }
-        });
-
-        var _dataLoaded = false;
-
-        /**
-         * The tab's data source, used for loading content dynamically.
-         * @config dataSrc
-         * @type String
-         */
-        this.register('dataSrc', {
-            value: attr.dataSrc
-        });
-
-        /**
-         * Whether or not content should be reloaded for every view.
-         * @config cacheData
-         * @type Boolean
-         * @default false
-         */
-        this.register('cacheData', {
-            value: attr.cacheData || false,
-            validator: Lang.isBoolean
-        });
-
-        /**
-         * The method to use for the data request.
-         * @config loadMethod
-         * @type String
-         * @default "GET"
-         */
-        this.register('loadMethod', {
-            value: attr.loadMethod || 'GET',
-            validator: Lang.isString
-        });
-
-        /**
-         * Whether or not any data has been loaded from the server.
-         * @config dataLoaded
-         * @type Boolean
-         */
-        this.register('dataLoaded', {
-            value: false,
-            validator: Lang.isBoolean,
-            writeOnce: true
-        });
-
-        /**
-         * Number if milliseconds before aborting and calling failure handler.
-         * @config dataTimeout
-         * @type Number
-         * @default null
-         */
-        this.register('dataTimeout', {
-            value: attr.dataTimeout || null,
-            validator: Lang.isNumber
-        });
-
-        /**
-         * Whether or not the tab is currently active.
-         * If a dataSrc is set for the tab, the content will be loaded from
-         * the given source.
-         * @config active
-         * @type Boolean
-         */
-        this.register('active', {
-            value: attr.active || this.hasClass(this.ACTIVE_CLASSNAME),
-            method: function(value) {
-                if (value === true) {
-                    this.addClass(this.ACTIVE_CLASSNAME);
-                    this.set('title', 'active');
-                } else {
-                    this.removeClass(this.ACTIVE_CLASSNAME);
-                    this.set('title', '');
-                }
-            },
-            validator: function(value) {
-                return Lang.isBoolean(value) && !this.get('disabled') ;
-            }
-        });
-
-        /**
-         * Whether or not the tab is disabled.
-         * @config disabled
-         * @type Boolean
-         */
-        this.register('disabled', {
-            value: attr.disabled || this.hasClass(this.DISABLED_CLASSNAME),
-            method: function(value) {
-                if (value === true) {
-                    Dom.addClass(this.get('element'), this.DISABLED_CLASSNAME);
-                } else {
-                    Dom.removeClass(this.get('element'), this.DISABLED_CLASSNAME);
-                }
-            },
-            validator: Lang.isBoolean
-        });
-
-        /**
-         * The href of the tab's anchor element.
-         * @config href
-         * @type String
-         * @default '#'
-         */
-        this.register('href', {
-            value: attr.href || '#',
-            method: function(value) {
-                this.getElementsByTagName('a')[0].href = value;
-            },
-            validator: Lang.isString
-        });
-
-        /**
-         * The Whether or not the tab's content is visible.
-         * @config contentVisible
-         * @type Boolean
-         * @default false
-         */
-        this.register('contentVisible', {
-            value: attr.contentVisible,
-            method: function(value) {
-                if (value == true) {
-                    this.get('contentEl').style.display = 'block';
-
-                    if ( this.get('dataSrc') ) {
-                     // load dynamic content unless already loaded and caching
-                        if ( !this.get('dataLoaded') || !this.get('cacheData') ) {
-                            _dataConnect.call(this);
-                        }
-                    }
-                } else {
-                    this.get('contentEl').style.display = 'none';
-                }
-            },
-            validator: Lang.isBoolean
-        });
-    };
-
-    var _createTabElement = function(attr) {
-        var el = document.createElement('li');
-        var a = document.createElement('a');
-
-        a.href = attr.href || '#';
-
-        el.appendChild(a);
-
-        var label = attr.label || null;
-        var labelEl = attr.labelEl || null;
-
-        if (labelEl) { // user supplied labelEl
-            if (!label) { // user supplied label
-                label = _getLabel.call(this, labelEl);
-            }
-        } else {
-            labelEl = _createlabelEl.call(this);
-        }
-
-        a.appendChild(labelEl);
-
-        return el;
-    };
-
-    var _getlabelEl = function() {
-        return this.getElementsByTagName(this.LABEL_TAGNAME)[0];
-    };
-
-    var _createlabelEl = function() {
-        var el = document.createElement(this.LABEL_TAGNAME);
-        return el;
-    };
-
-    var _setLabel = function(label) {
-        var el = this.get('labelEl');
-        el.innerHTML = label;
-    };
-
-    var _getLabel = function() {
-        var label,
-            el = this.get('labelEl');
-
-            if (!el) {
-                return undefined;
-            }
-
-        return el.innerHTML;
-    };
-
-    var _dataConnect = function() {
-        if (!YAHOO.util.Connect) {
-            YAHOO.log('YAHOO.util.Connect dependency not met',
-                    'error', 'Tab');
-            return false;
-        }
-
-        Dom.addClass(this.get('contentEl').parentNode, this.LOADING_CLASSNAME);
-
-        this.dataConnection = YAHOO.util.Connect.asyncRequest(
-            this.get('loadMethod'),
-            this.get('dataSrc'),
-            {
-                success: function(o) {
-                    this.loadHandler.success.call(this, o);
-                    this.set('dataLoaded', true);
-                    this.dataConnection = null;
-                    Dom.removeClass(this.get('contentEl').parentNode,
-                            this.LOADING_CLASSNAME);
-                },
-                failure: function(o) {
-                    this.loadHandler.failure.call(this, o);
-                    this.dataConnection = null;
-                    Dom.removeClass(this.get('contentEl').parentNode,
-                            this.LOADING_CLASSNAME);
-                },
-                scope: this,
-                timeout: this.get('dataTimeout')
-            }
-        );
-    };
-
-    YAHOO.widget.Tab = Tab;
-
-    /**
-     * Fires before the active state is changed.
-     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
-     * <p>If handler returns false, the change will be cancelled, and the value will not
-     * be set.</p>
-     * <p><strong>Event fields:</strong><br>
-     * <code>&lt;String&gt; type</code> beforeActiveChange<br>
-     * <code>&lt;Boolean&gt;
-     * prevValue</code> the current value<br>
-     * <code>&lt;Boolean&gt;
-     * newValue</code> the new value</p>
-     * <p><strong>Usage:</strong><br>
-     * <code>var handler = function(e) {var previous = e.prevValue};<br>
-     * myTabs.addListener('beforeActiveChange', handler);</code></p>
-     * @event beforeActiveChange
-     */
-
-    /**
-     * Fires after the active state is changed.
-     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
-     * <p><strong>Event fields:</strong><br>
-     * <code>&lt;String&gt; type</code> activeChange<br>
-     * <code>&lt;Boolean&gt;
-     * prevValue</code> the previous value<br>
-     * <code>&lt;Boolean&gt;
-     * newValue</code> the updated value</p>
-     * <p><strong>Usage:</strong><br>
-     * <code>var handler = function(e) {var previous = e.prevValue};<br>
-     * myTabs.addListener('activeChange', handler);</code></p>
-     * @event activeChange
-     */
-
-    /**
-     * Fires before the tab label is changed.
-     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
-     * <p>If handler returns false, the change will be cancelled, and the value will not
-     * be set.</p>
-     * <p><strong>Event fields:</strong><br>
-     * <code>&lt;String&gt; type</code> beforeLabelChange<br>
-     * <code>&lt;String&gt;
-     * prevValue</code> the current value<br>
-     * <code>&lt;String&gt;
-     * newValue</code> the new value</p>
-     * <p><strong>Usage:</strong><br>
-     * <code>var handler = function(e) {var previous = e.prevValue};<br>
-     * myTabs.addListener('beforeLabelChange', handler);</code></p>
-     * @event beforeLabelChange
-     */
-
-    /**
-     * Fires after the tab label is changed.
-     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
-     * <p><strong>Event fields:</strong><br>
-     * <code>&lt;String&gt; type</code> labelChange<br>
-     * <code>&lt;String&gt;
-     * prevValue</code> the previous value<br>
-     * <code>&lt;String&gt;
-     * newValue</code> the updated value</p>
-     * <p><strong>Usage:</strong><br>
-     * <code>var handler = function(e) {var previous = e.prevValue};<br>
-     * myTabs.addListener('labelChange', handler);</code></p>
-     * @event labelChange
-     */
-
-    /**
-     * Fires before the tab content is changed.
-     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
-     * <p>If handler returns false, the change will be cancelled, and the value will not
-     * be set.</p>
-     * <p><strong>Event fields:</strong><br>
-     * <code>&lt;String&gt; type</code> beforeContentChange<br>
-     * <code>&lt;String&gt;
-     * prevValue</code> the current value<br>
-     * <code>&lt;String&gt;
-     * newValue</code> the new value</p>
-     * <p><strong>Usage:</strong><br>
-     * <code>var handler = function(e) {var previous = e.prevValue};<br>
-     * myTabs.addListener('beforeContentChange', handler);</code></p>
-     * @event beforeContentChange
-     */
-
-    /**
-     * Fires after the tab content is changed.
-     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
-     * <p><strong>Event fields:</strong><br>
-     * <code>&lt;String&gt; type</code> contentChange<br>
-     * <code>&lt;String&gt;
-     * prevValue</code> the previous value<br>
-     * <code>&lt;Boolean&gt;
-     * newValue</code> the updated value</p>
-     * <p><strong>Usage:</strong><br>
-     * <code>var handler = function(e) {var previous = e.prevValue};<br>
-     * myTabs.addListener('contentChange', handler);</code></p>
-     * @event contentChange
-     */
-})();(function() {
-
-    /**
-     * The tabview module provides a widget for managing content bound to tabs.
-     * @module tabview
-     *
-     */
-    /**
-     * A widget to control tabbed views.
-     * @namespace YAHOO.widget
-     * @class TabView
-     * @extends YAHOO.util.Element
-     * @constructor
-     * @param {HTMLElement | String | Object} el(optional) The html
-     * element that represents the TabView, or the attribute object to use.
-     * An element will be created if none provided.
-     * @param {Object} attr (optional) A key map of the tabView's
-     * initial attributes.  Ignored if first arg is attributes object.
-     */
-    YAHOO.widget.TabView = function(el, attr) {
-        attr = attr || {};
-        if (arguments.length == 1 && !Lang.isString(el) && !el.nodeName) {
-            attr = el; // treat first arg as attr object
-            el = attr.element || null;
-        }
-
-        if (!el && !attr.element) { // create if we dont have one
-            el = _createTabViewElement.call(this, attr);
-        }
-    	YAHOO.widget.TabView.superclass.constructor.call(this, el, attr);
-    };
-
-    YAHOO.extend(YAHOO.widget.TabView, YAHOO.util.Element);
-
-    var proto = YAHOO.widget.TabView.prototype;
-    var Dom = YAHOO.util.Dom;
-    var Lang = YAHOO.util.Lang;
-    var Event = YAHOO.util.Event;
-    var Tab = YAHOO.widget.Tab;
-
-
-    /**
-     * The className to add when building from scratch.
-     * @property CLASSNAME
-     * @default "navset"
-     */
-    proto.CLASSNAME = 'yui-navset';
-
-    /**
-     * The className of the HTMLElement containing the TabView's tab elements
-     * to look for when building from existing markup, or to add when building
-     * from scratch.
-     * All childNodes of the tab container are treated as Tabs when building
-     * from existing markup.
-     * @property TAB_PARENT_CLASSNAME
-     * @default "nav"
-     */
-    proto.TAB_PARENT_CLASSNAME = 'yui-nav';
-
-    /**
-     * The className of the HTMLElement containing the TabView's label elements
-     * to look for when building from existing markup, or to add when building
-     * from scratch.
-     * All childNodes of the content container are treated as content elements when
-     * building from existing markup.
-     * @property CONTENT_PARENT_CLASSNAME
-     * @default "nav-content"
-     */
-    proto.CONTENT_PARENT_CLASSNAME = 'yui-content';
-
-    proto._tabParent = null;
-    proto._contentParent = null;
-
-    /**
-     * Adds a Tab to the TabView instance.
-     * If no index is specified, the tab is added to the end of the tab list.
-     * @method addTab
-     * @param {YAHOO.widget.Tab} tab A Tab instance to add.
-     * @param {Integer} index The position to add the tab.
-     * @return void
-     */
-    proto.addTab = function(tab, index) {
-        var tabs = this.get('tabs');
-        if (!tabs) { // not ready yet
-            this._queue[this._queue.length] = ['addTab', arguments];
-            return false;
-        }
-
-        index = (index === undefined) ? tabs.length : index;
-
-        var before = this.getTab(index);
-
-        var self = this;
-        var el = this.get('element');
-        var tabParent = this._tabParent;
-        var contentParent = this._contentParent;
-
-        var tabElement = tab.get('element');
-        var contentEl = tab.get('contentEl');
-
-        if ( before ) {
-            tabParent.insertBefore(tabElement, before.get('element'));
-        } else {
-            tabParent.appendChild(tabElement);
-        }
-
-        if ( contentEl && !Dom.isAncestor(contentParent, contentEl) ) {
-            contentParent.appendChild(contentEl);
-        }
-
-        if ( !tab.get('active') ) {
-            tab.set('contentVisible', false, true); /* hide if not active */
-        } else {
-            this.set('activeTab', tab, true);
-
-        }
-
-        var activate = function(e) {
-            YAHOO.util.Event.preventDefault(e);
-            self.set('activeTab', this);
-        };
-
-        tab.addListener( tab.get('activationEvent'), activate);
-
-        tab.addListener('activationEventChange', function(e) {
-            if (e.prevValue != e.newValue) {
-                tab.removeListener(e.prevValue, activate);
-                tab.addListener(e.newValue, activate);
-            }
-        });
-
-        tabs.splice(index, 0, tab);
-    };
-
-    /**
-     * Routes childNode events.
-     * @method DOMEventHandler
-     * @param {event} e The Dom event that is being handled.
-     * @return void
-     */
-    proto.DOMEventHandler = function(e) {
-        var el = this.get('element');
-        var target = YAHOO.util.Event.getTarget(e);
-        var tabParent = this._tabParent;
-
-        if (Dom.isAncestor(tabParent, target) ) {
-            var tabEl;
-            var tab = null;
-            var contentEl;
-            var tabs = this.get('tabs');
-
-            for (var i = 0, len = tabs.length; i < len; i++) {
-                tabEl = tabs[i].get('element');
-                contentEl = tabs[i].get('contentEl');
-
-                if ( target == tabEl || Dom.isAncestor(tabEl, target) ) {
-                    tab = tabs[i];
-                    break; // note break
-                }
-            }
-
-            if (tab) {
-                tab.fireEvent(e.type, e);
-            }
-        }
-    };
-
-    /**
-     * Returns the Tab instance at the specified index.
-     * @method getTab
-     * @param {Integer} index The position of the Tab.
-     * @return YAHOO.widget.Tab
-     */
-    proto.getTab = function(index) {
-    	return this.get('tabs')[index];
-    };
-
-    /**
-     * Returns the index of given tab.
-     * @method getTabIndex
-     * @param {YAHOO.widget.Tab} tab The tab whose index will be returned.
-     * @return int
-     */
-    proto.getTabIndex = function(tab) {
-        var index = null;
-        var tabs = this.get('tabs');
-    	for (var i = 0, len = tabs.length; i < len; ++i) {
-            if (tab == tabs[i]) {
-                index = i;
-                break;
-            }
-        }
-
-        return index;
-    };
-
-    /**
-     * Removes the specified Tab from the TabView.
-     * @method removeTab
-     * @param {YAHOO.widget.Tab} item The Tab instance to be removed.
-     * @return void
-     */
-    proto.removeTab = function(tab) {
-        var tabCount = this.get('tabs').length;
-
-        var index = this.getTabIndex(tab);
-        var nextIndex = index + 1;
-        if ( tab == this.get('activeTab') ) { // select next tab
-            if (tabCount > 1) {
-                if (index + 1 == tabCount) {
-                    this.set('activeIndex', index - 1);
-                } else {
-                    this.set('activeIndex', index + 1);
-                }
-            }
-        }
-
-        this._tabParent.removeChild( tab.get('element') );
-        this._contentParent.removeChild( tab.get('contentEl') );
-        this._configs.tabs.value.splice(index, 1);
-
-    };
-
-    /**
-     * Provides a readable name for the TabView instance.
-     * @method toString
-     * @return String
-     */
-    proto.toString = function() {
-        var name = this.get('id') || this.get('tagName');
-        return "TabView " + name;
-    };
-
-    /**
-     * The transiton to use when switching between tabs.
-     * @method contentTransition
-     */
-    proto.contentTransition = function(newTab, oldTab) {
-        newTab.set('contentVisible', true);
-        oldTab.set('contentVisible', false);
-    };
-
-    /**
-     * Registers TabView specific properties.
-     * @method initAttributes
-     * @param {Object} attr Hash of initial attributes
-     */
-    proto.initAttributes = function(attr) {
-        YAHOO.widget.TabView.superclass.initAttributes.call(this, attr);
-
-        if (!attr.orientation) {
-            attr.orientation = 'top';
-        }
-
-        var el = this.get('element');
-
-        /**
-         * The Tabs belonging to the TabView instance.
-         * @config tabs
-         * @type Array
-         */
-        this.register('tabs', {
-            value: [],
-            readOnly: true
-        });
-
-        /**
-         * The container of the tabView's label elements.
-         * @property _tabParent
-         * @private
-         * @type HTMLElement
-         */
-        this._tabParent =
-                this.getElementsByClassName(this.TAB_PARENT_CLASSNAME,
-                        'ul' )[0] || _createTabParent.call(this);
-
-        /**
-         * The container of the tabView's content elements.
-         * @property _contentParent
-         * @type HTMLElement
-         * @private
-         */
-        this._contentParent =
-                this.getElementsByClassName(this.CONTENT_PARENT_CLASSNAME,
-                        'div')[0] ||  _createContentParent.call(this);
-
-        /**
-         * How the Tabs should be oriented relative to the TabView.
-         * @config orientation
-         * @type String
-         * @default "top"
-         */
-        this.register('orientation', {
-            value: attr.orientation,
-            method: function(value) {
-                var current = this.get('orientation');
-                this.addClass('yui-navset-' + value);
-
-                if (current != value) {
-                    this.removeClass('yui-navset-' + current);
-                }
-
-                switch(value) {
-                    case 'bottom':
-                    this.appendChild(this._tabParent);
-                    break;
-                }
-            }
-        });
-
-        /**
-         * The index of the tab currently active.
-         * @config activeIndex
-         * @type Int
-         */
-        this.register('activeIndex', {
-            value: attr.activeIndex,
-            method: function(value) {
-                this.set('activeTab', this.getTab(value));
-            },
-            validator: function(value) {
-                return !this.getTab(value).get('disabled'); // cannot activate if disabled
-            }
-        });
-
-        /**
-         * The tab currently active.
-         * @config activeTab
-         * @type YAHOO.widget.Tab
-         */
-        this.register('activeTab', {
-            value: attr.activeTab,
-            method: function(tab) {
-                var activeTab = this.get('activeTab');
-
-                if (tab) {
-                    tab.set('active', true);
-                }
-
-                if (activeTab && activeTab != tab) {
-                    activeTab.set('active', false);
-                }
-
-                if (activeTab && tab != activeTab) { // no transition if only 1
-                    this.contentTransition(tab, activeTab);
-                } else if (tab) {
-                    tab.set('contentVisible', true);
-                }
-            },
-            validator: function(value) {
-                return !value.get('disabled'); // cannot activate if disabled
-            }
-        });
-
-        if ( this._tabParent ) {
-            _initTabs.call(this);
-        }
-
-        for (var type in this.DOM_EVENTS) {
-            if ( this.DOM_EVENTS.hasOwnProperty(type) ) {
-                this.addListener.call(this, type, this.DOMEventHandler);
-            }
-        }
-    };
-
-    /**
-     * Creates Tab instances from a collection of HTMLElements.
-     * @method createTabs
-     * @private
-     * @param {Array|HTMLCollection} elements The elements to use for Tabs.
-     * @return void
-     */
-    var _initTabs = function() {
-        var tab,
-            attr,
-            contentEl;
-
-        var el = this.get('element');
-        var tabs = _getChildNodes(this._tabParent);
-        var contentElements = _getChildNodes(this._contentParent);
-
-        for (var i = 0, len = tabs.length; i < len; ++i) {
-            attr = {};
-
-            if (contentElements[i]) {
-                attr.contentEl = contentElements[i];
-            }
-
-            tab = new YAHOO.widget.Tab(tabs[i], attr);
-            this.addTab(tab);
-
-            if (tab.hasClass(tab.ACTIVE_CLASSNAME) ) {
-                this._configs.activeTab.value = tab; // dont invoke method
-            }
-        }
-    };
-
-    var _createTabViewElement = function(attr) {
-        var el = document.createElement('div');
-
-        if ( this.CLASSNAME ) {
-            el.className = this.CLASSNAME;
-        }
-
-        return el;
-    };
-
-    var _createTabParent = function(attr) {
-        var el = document.createElement('ul');
-
-        if ( this.TAB_PARENT_CLASSNAME ) {
-            el.className = this.TAB_PARENT_CLASSNAME;
-        }
-
-        this.get('element').appendChild(el);
-
-        return el;
-    };
-
-    var _createContentParent = function(attr) {
-        var el = document.createElement('div');
-
-        if ( this.CONTENT_PARENT_CLASSNAME ) {
-            el.className = this.CONTENT_PARENT_CLASSNAME;
-        }
-
-        this.get('element').appendChild(el);
-
-        return el;
-    };
-
-    var _getChildNodes = function(el) {
-        var nodes = [];
-        var childNodes = el.childNodes;
-
-        for (var i = 0, len = childNodes.length; i < len; ++i) {
-            if (childNodes[i].nodeType == 1) {
-                nodes[nodes.length] = childNodes[i];
-            }
-        }
-
-        return nodes;
-    };
-
-/**
- * Fires before the activeTab is changed.
- * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
- * <p>If handler returns false, the change will be cancelled, and the value will not
- * be set.</p>
- * <p><strong>Event fields:</strong><br>
- * <code>&lt;String&gt; type</code> beforeActiveTabChange<br>
- * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
- * prevValue</code> the currently active tab<br>
- * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
- * newValue</code> the tab to be made active</p>
- * <p><strong>Usage:</strong><br>
- * <code>var handler = function(e) {var previous = e.prevValue};<br>
- * myTabs.addListener('beforeActiveTabChange', handler);</code></p>
- * @event beforeActiveTabChange
- */
-
-/**
- * Fires after the activeTab is changed.
- * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
- * <p><strong>Event fields:</strong><br>
- * <code>&lt;String&gt; type</code> activeTabChange<br>
- * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
- * prevValue</code> the formerly active tab<br>
- * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
- * newValue</code> the new active tab</p>
- * <p><strong>Usage:</strong><br>
- * <code>var handler = function(e) {var previous = e.prevValue};<br>
- * myTabs.addListener('activeTabChange', handler);</code></p>
- * @event activeTabChange
- */
-
-/**
- * Fires before the orientation is changed.
- * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
- * <p>If handler returns false, the change will be cancelled, and the value will not
- * be set.</p>
- * <p><strong>Event fields:</strong><br>
- * <code>&lt;String&gt; type</code> beforeOrientationChange<br>
- * <code>&lt;String&gt;
- * prevValue</code> the current orientation<br>
- * <code>&lt;String&gt;
- * newValue</code> the new orientation to be applied</p>
- * <p><strong>Usage:</strong><br>
- * <code>var handler = function(e) {var previous = e.prevValue};<br>
- * myTabs.addListener('beforeOrientationChange', handler);</code></p>
- * @event beforeOrientationChange
- */
-
-/**
- * Fires after the orientation is changed.
- * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
- * <p><strong>Event fields:</strong><br>
- * <code>&lt;String&gt; type</code> orientationChange<br>
- * <code>&lt;String&gt;
- * prevValue</code> the former orientation<br>
- * <code>&lt;String&gt;
- * newValue</code> the new orientation</p>
- * <p><strong>Usage:</strong><br>
- * <code>var handler = function(e) {var previous = e.prevValue};<br>
- * myTabs.addListener('orientationChange', handler);</code></p>
- * @event orientationChange
- */
-})();
\ No newline at end of file
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+(function() {
+
+    /**
+     * The tabview module provides a widget for managing content bound to tabs.
+     * @module tabview
+     * @requires yahoo, dom, event, element
+     *
+     */
+    /**
+     * A widget to control tabbed views.
+     * @namespace YAHOO.widget
+     * @class TabView
+     * @extends YAHOO.util.Element
+     * @constructor
+     * @param {HTMLElement | String | Object} el(optional) The html 
+     * element that represents the TabView, or the attribute object to use. 
+     * An element will be created if none provided.
+     * @param {Object} attr (optional) A key map of the tabView's 
+     * initial attributes.  Ignored if first arg is attributes object.
+     */
+    YAHOO.widget.TabView = function(el, attr) {
+        attr = attr || {};
+        if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
+            attr = el; // treat first arg as attr object
+            el = attr.element || null;
+        }
+        
+        if (!el && !attr.element) { // create if we dont have one
+            el = _createTabViewElement.call(this, attr);
+        }
+    	YAHOO.widget.TabView.superclass.constructor.call(this, el, attr); 
+    };
+
+    YAHOO.extend(YAHOO.widget.TabView, YAHOO.util.Element);
+    
+    var proto = YAHOO.widget.TabView.prototype;
+    var Dom = YAHOO.util.Dom;
+    var Event = YAHOO.util.Event;
+    var Tab = YAHOO.widget.Tab;
+    
+    
+    /**
+     * The className to add when building from scratch. 
+     * @property CLASSNAME
+     * @default "navset"
+     */
+    proto.CLASSNAME = 'yui-navset';
+    
+    /**
+     * The className of the HTMLElement containing the TabView's tab elements
+     * to look for when building from existing markup, or to add when building
+     * from scratch. 
+     * All childNodes of the tab container are treated as Tabs when building
+     * from existing markup.
+     * @property TAB_PARENT_CLASSNAME
+     * @default "nav"
+     */
+    proto.TAB_PARENT_CLASSNAME = 'yui-nav';
+    
+    /**
+     * The className of the HTMLElement containing the TabView's label elements
+     * to look for when building from existing markup, or to add when building
+     * from scratch. 
+     * All childNodes of the content container are treated as content elements when
+     * building from existing markup.
+     * @property CONTENT_PARENT_CLASSNAME
+     * @default "nav-content"
+     */
+    proto.CONTENT_PARENT_CLASSNAME = 'yui-content';
+    
+    proto._tabParent = null;
+    proto._contentParent = null; 
+    
+    /**
+     * Adds a Tab to the TabView instance.  
+     * If no index is specified, the tab is added to the end of the tab list.
+     * @method addTab
+     * @param {YAHOO.widget.Tab} tab A Tab instance to add.
+     * @param {Integer} index The position to add the tab. 
+     * @return void
+     */
+    proto.addTab = function(tab, index) {
+        var tabs = this.get('tabs');
+        if (!tabs) { // not ready yet
+            this._queue[this._queue.length] = ['addTab', arguments];
+            return false;
+        }
+        
+        index = (index === undefined) ? tabs.length : index;
+        
+        var before = this.getTab(index);
+        
+        var self = this;
+        var el = this.get('element');
+        var tabParent = this._tabParent;
+        var contentParent = this._contentParent;
+
+        var tabElement = tab.get('element');
+        var contentEl = tab.get('contentEl');
+
+        if ( before ) {
+            tabParent.insertBefore(tabElement, before.get('element'));
+        } else {
+            tabParent.appendChild(tabElement);
+        }
+
+        if ( contentEl && !Dom.isAncestor(contentParent, contentEl) ) {
+            contentParent.appendChild(contentEl);
+        }
+        
+        if ( !tab.get('active') ) {
+            tab.set('contentVisible', false, true); /* hide if not active */
+        } else {
+            this.set('activeTab', tab, true);
+            
+        }
+
+        var activate = function(e) {
+            YAHOO.util.Event.preventDefault(e);
+            self.set('activeTab', this);
+        };
+        
+        tab.addListener( tab.get('activationEvent'), activate);
+        
+        tab.addListener('activationEventChange', function(e) {
+            if (e.prevValue != e.newValue) {
+                tab.removeListener(e.prevValue, activate);
+                tab.addListener(e.newValue, activate);
+            }
+        });
+        
+        tabs.splice(index, 0, tab);
+    };
+
+    /**
+     * Routes childNode events.
+     * @method DOMEventHandler
+     * @param {event} e The Dom event that is being handled.
+     * @return void
+     */
+    proto.DOMEventHandler = function(e) {
+        var el = this.get('element');
+        var target = YAHOO.util.Event.getTarget(e);
+        var tabParent = this._tabParent;
+        
+        if (Dom.isAncestor(tabParent, target) ) {
+            var tabEl;
+            var tab = null;
+            var contentEl;
+            var tabs = this.get('tabs');
+
+            for (var i = 0, len = tabs.length; i < len; i++) {
+                tabEl = tabs[i].get('element');
+                contentEl = tabs[i].get('contentEl');
+
+                if ( target == tabEl || Dom.isAncestor(tabEl, target) ) {
+                    tab = tabs[i];
+                    break; // note break
+                }
+            } 
+            
+            if (tab) {
+                tab.fireEvent(e.type, e);
+            }
+        }
+    };
+    
+    /**
+     * Returns the Tab instance at the specified index.
+     * @method getTab
+     * @param {Integer} index The position of the Tab.
+     * @return YAHOO.widget.Tab
+     */
+    proto.getTab = function(index) {
+    	return this.get('tabs')[index];
+    };
+    
+    /**
+     * Returns the index of given tab.
+     * @method getTabIndex
+     * @param {YAHOO.widget.Tab} tab The tab whose index will be returned.
+     * @return int
+     */
+    proto.getTabIndex = function(tab) {
+        var index = null;
+        var tabs = this.get('tabs');
+    	for (var i = 0, len = tabs.length; i < len; ++i) {
+            if (tab == tabs[i]) {
+                index = i;
+                break;
+            }
+        }
+        
+        return index;
+    };
+    
+    /**
+     * Removes the specified Tab from the TabView.
+     * @method removeTab
+     * @param {YAHOO.widget.Tab} item The Tab instance to be removed.
+     * @return void
+     */
+    proto.removeTab = function(tab) {
+        var tabCount = this.get('tabs').length;
+
+        var index = this.getTabIndex(tab);
+        var nextIndex = index + 1;
+        if ( tab == this.get('activeTab') ) { // select next tab
+            if (tabCount > 1) {
+                if (index + 1 == tabCount) {
+                    this.set('activeIndex', index - 1);
+                } else {
+                    this.set('activeIndex', index + 1);
+                }
+            }
+        }
+        
+        this._tabParent.removeChild( tab.get('element') );
+        this._contentParent.removeChild( tab.get('contentEl') );
+        this._configs.tabs.value.splice(index, 1);
+    	
+    };
+    
+    /**
+     * Provides a readable name for the TabView instance.
+     * @method toString
+     * @return String
+     */
+    proto.toString = function() {
+        var name = this.get('id') || this.get('tagName');
+        return "TabView " + name; 
+    };
+    
+    /**
+     * The transiton to use when switching between tabs.
+     * @method contentTransition
+     */
+    proto.contentTransition = function(newTab, oldTab) {
+        newTab.set('contentVisible', true);
+        oldTab.set('contentVisible', false);
+    };
+    
+    /**
+     * setAttributeConfigs TabView specific properties.
+     * @method initAttributes
+     * @param {Object} attr Hash of initial attributes
+     */
+    proto.initAttributes = function(attr) {
+        YAHOO.widget.TabView.superclass.initAttributes.call(this, attr);
+        
+        if (!attr.orientation) {
+            attr.orientation = 'top';
+        }
+        
+        var el = this.get('element');
+        
+        /**
+         * The Tabs belonging to the TabView instance.
+         * @config tabs
+         * @type Array
+         */
+        this.setAttributeConfig('tabs', {
+            value: [],
+            readOnly: true
+        });
+
+        /**
+         * The container of the tabView's label elements.
+         * @property _tabParent
+         * @private
+         * @type HTMLElement
+         */
+        this._tabParent = 
+                this.getElementsByClassName(this.TAB_PARENT_CLASSNAME,
+                        'ul' )[0] || _createTabParent.call(this);
+            
+        /**
+         * The container of the tabView's content elements.
+         * @property _contentParent
+         * @type HTMLElement
+         * @private
+         */
+        this._contentParent = 
+                this.getElementsByClassName(this.CONTENT_PARENT_CLASSNAME,
+                        'div')[0] ||  _createContentParent.call(this);
+        
+        /**
+         * How the Tabs should be oriented relative to the TabView.
+         * @config orientation
+         * @type String
+         * @default "top"
+         */
+        this.setAttributeConfig('orientation', {
+            value: attr.orientation,
+            method: function(value) {
+                var current = this.get('orientation');
+                this.addClass('yui-navset-' + value);
+                
+                if (current != value) {
+                    this.removeClass('yui-navset-' + current);
+                }
+                
+                switch(value) {
+                    case 'bottom':
+                    this.appendChild(this._tabParent);
+                    break;
+                }
+            }
+        });
+        
+        /**
+         * The index of the tab currently active.
+         * @config activeIndex
+         * @type Int
+         */
+        this.setAttributeConfig('activeIndex', {
+            value: attr.activeIndex,
+            method: function(value) {
+                this.set('activeTab', this.getTab(value));
+            },
+            validator: function(value) {
+                return !this.getTab(value).get('disabled'); // cannot activate if disabled
+            }
+        });
+        
+        /**
+         * The tab currently active.
+         * @config activeTab
+         * @type YAHOO.widget.Tab
+         */
+        this.setAttributeConfig('activeTab', {
+            value: attr.activeTab,
+            method: function(tab) {
+                var activeTab = this.get('activeTab');
+                
+                if (tab) {  
+                    tab.set('active', true);
+                    this._configs['activeIndex'].value = this.getTabIndex(tab); // keep in sync
+                }
+                
+                if (activeTab && activeTab != tab) {
+                    activeTab.set('active', false);
+                }
+                
+                if (activeTab && tab != activeTab) { // no transition if only 1
+                    this.contentTransition(tab, activeTab);
+                } else if (tab) {
+                    tab.set('contentVisible', true);
+                }
+            },
+            validator: function(value) {
+                return !value.get('disabled'); // cannot activate if disabled
+            }
+        });
+
+        if ( this._tabParent ) {
+            _initTabs.call(this);
+        }
+        
+        for (var type in this.DOM_EVENTS) {
+            if ( YAHOO.lang.hasOwnProperty(this.DOM_EVENTS, type) ) {
+                this.addListener.call(this, type, this.DOMEventHandler);
+            }
+        }
+    };
+    
+    /**
+     * Creates Tab instances from a collection of HTMLElements.
+     * @method createTabs
+     * @private
+     * @param {Array|HTMLCollection} elements The elements to use for Tabs.
+     * @return void
+     */
+    var _initTabs = function() {
+        var tab,
+            attr,
+            contentEl;
+            
+        var el = this.get('element');   
+        var tabs = _getChildNodes(this._tabParent);
+        var contentElements = _getChildNodes(this._contentParent);
+
+        for (var i = 0, len = tabs.length; i < len; ++i) {
+            attr = {};
+            
+            if (contentElements[i]) {
+                attr.contentEl = contentElements[i];
+            }
+
+            tab = new YAHOO.widget.Tab(tabs[i], attr);
+            this.addTab(tab);
+            
+            if (tab.hasClass(tab.ACTIVE_CLASSNAME) ) {
+                this._configs.activeTab.value = tab; // dont invoke method
+            }
+        }
+    };
+    
+    var _createTabViewElement = function(attr) {
+        var el = document.createElement('div');
+
+        if ( this.CLASSNAME ) {
+            el.className = this.CLASSNAME;
+        }
+        
+        return el;
+    };
+    
+    var _createTabParent = function(attr) {
+        var el = document.createElement('ul');
+
+        if ( this.TAB_PARENT_CLASSNAME ) {
+            el.className = this.TAB_PARENT_CLASSNAME;
+        }
+        
+        this.get('element').appendChild(el);
+        
+        return el;
+    };
+    
+    var _createContentParent = function(attr) {
+        var el = document.createElement('div');
+
+        if ( this.CONTENT_PARENT_CLASSNAME ) {
+            el.className = this.CONTENT_PARENT_CLASSNAME;
+        }
+        
+        this.get('element').appendChild(el);
+        
+        return el;
+    };
+    
+    var _getChildNodes = function(el) {
+        var nodes = [];
+        var childNodes = el.childNodes;
+        
+        for (var i = 0, len = childNodes.length; i < len; ++i) {
+            if (childNodes[i].nodeType == 1) {
+                nodes[nodes.length] = childNodes[i];
+            }
+        }
+        
+        return nodes;
+    };
+
+/**
+ * Fires before the activeTab is changed.
+ * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+ * <p>If handler returns false, the change will be cancelled, and the value will not
+ * be set.</p>
+ * <p><strong>Event fields:</strong><br>
+ * <code>&lt;String&gt; type</code> beforeActiveTabChange<br>
+ * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
+ * prevValue</code> the currently active tab<br>
+ * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
+ * newValue</code> the tab to be made active</p>
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var previous = e.prevValue};<br>
+ * myTabs.addListener('beforeActiveTabChange', handler);</code></p>
+ * @event beforeActiveTabChange
+ */
+    
+/**
+ * Fires after the activeTab is changed.
+ * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code>&lt;String&gt; type</code> activeTabChange<br>
+ * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
+ * prevValue</code> the formerly active tab<br>
+ * <code>&lt;<a href="YAHOO.widget.Tab.html">YAHOO.widget.Tab</a>&gt;
+ * newValue</code> the new active tab</p>
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var previous = e.prevValue};<br>
+ * myTabs.addListener('activeTabChange', handler);</code></p>
+ * @event activeTabChange
+ */
+ 
+/**
+ * Fires before the orientation is changed.
+ * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+ * <p>If handler returns false, the change will be cancelled, and the value will not
+ * be set.</p>
+ * <p><strong>Event fields:</strong><br>
+ * <code>&lt;String&gt; type</code> beforeOrientationChange<br>
+ * <code>&lt;String&gt;
+ * prevValue</code> the current orientation<br>
+ * <code>&lt;String&gt;
+ * newValue</code> the new orientation to be applied</p>
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var previous = e.prevValue};<br>
+ * myTabs.addListener('beforeOrientationChange', handler);</code></p>
+ * @event beforeOrientationChange
+ */
+    
+/**
+ * Fires after the orientation is changed.
+ * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code>&lt;String&gt; type</code> orientationChange<br>
+ * <code>&lt;String&gt;
+ * prevValue</code> the former orientation<br>
+ * <code>&lt;String&gt;
+ * newValue</code> the new orientation</p>
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var previous = e.prevValue};<br>
+ * myTabs.addListener('orientationChange', handler);</code></p>
+ * @event orientationChange
+ */
+})();
+
+(function() {
+    var Dom = YAHOO.util.Dom,
+        Event = YAHOO.util.Event;
+    
+    /**
+     * A representation of a Tab's label and content.
+     * @namespace YAHOO.widget
+     * @class Tab
+     * @extends YAHOO.util.Element
+     * @constructor
+     * @param element {HTMLElement | String} (optional) The html element that 
+     * represents the TabView. An element will be created if none provided.
+     * @param {Object} properties A key map of initial properties
+     */
+    var Tab = function(el, attr) {
+        attr = attr || {};
+        if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
+            attr = el;
+            el = attr.element;
+        }
+
+        if (!el && !attr.element) {
+            el = _createTabElement.call(this, attr);
+        }
+
+        this.loadHandler =  {
+            success: function(o) {
+                this.set('content', o.responseText);
+            },
+            failure: function(o) {
+            }
+        };
+        
+        Tab.superclass.constructor.call(this, el, attr);
+        
+        this.DOM_EVENTS = {}; // delegating to tabView
+    };
+
+    YAHOO.extend(Tab, YAHOO.util.Element);
+    var proto = Tab.prototype;
+    
+    /**
+     * The default tag name for a Tab's inner element.
+     * @property LABEL_INNER_TAGNAME
+     * @type String
+     * @default "em"
+     */
+    proto.LABEL_TAGNAME = 'em';
+    
+    /**
+     * The class name applied to active tabs.
+     * @property ACTIVE_CLASSNAME
+     * @type String
+     * @default "on"
+     */
+    proto.ACTIVE_CLASSNAME = 'selected';
+    
+    /**
+     * The class name applied to disabled tabs.
+     * @property DISABLED_CLASSNAME
+     * @type String
+     * @default "disabled"
+     */
+    proto.DISABLED_CLASSNAME = 'disabled';
+    
+    /**
+     * The class name applied to dynamic tabs while loading.
+     * @property LOADING_CLASSNAME
+     * @type String
+     * @default "disabled"
+     */
+    proto.LOADING_CLASSNAME = 'loading';
+
+    /**
+     * Provides a reference to the connection request object when data is
+     * loaded dynamically.
+     * @property dataConnection
+     * @type Object
+     */
+    proto.dataConnection = null;
+    
+    /**
+     * Object containing success and failure callbacks for loading data.
+     * @property loadHandler
+     * @type object
+     */
+    proto.loadHandler = null;
+    
+    /**
+     * Provides a readable name for the tab.
+     * @method toString
+     * @return String
+     */
+    proto.toString = function() {
+        var el = this.get('element');
+        var id = el.id || el.tagName;
+        return "Tab " + id; 
+    };
+    
+    /**
+     * setAttributeConfigs TabView specific properties.
+     * @method initAttributes
+     * @param {Object} attr Hash of initial attributes
+     */
+    proto.initAttributes = function(attr) {
+        attr = attr || {};
+        Tab.superclass.initAttributes.call(this, attr);
+        
+        var el = this.get('element');
+        
+        /**
+         * The event that triggers the tab's activation.
+         * @config activationEvent
+         * @type String
+         */
+        this.setAttributeConfig('activationEvent', {
+            value: attr.activationEvent || 'click'
+        });        
+
+        /**
+         * The element that contains the tab's label.
+         * @config labelEl
+         * @type HTMLElement
+         */
+        this.setAttributeConfig('labelEl', {
+            value: attr.labelEl || _getlabelEl.call(this),
+            method: function(value) {
+                var current = this.get('labelEl');
+
+                if (current) {
+                    if (current == value) {
+                        return false; // already set
+                    }
+                    
+                    this.replaceChild(value, current);
+                } else if (el.firstChild) { // ensure label is firstChild by default
+                    this.insertBefore(value, el.firstChild);
+                } else {
+                    this.appendChild(value);
+                }  
+            } 
+        });
+
+        /**
+         * The tab's label text (or innerHTML).
+         * @config label
+         * @type String
+         */
+        this.setAttributeConfig('label', {
+            value: attr.label || _getLabel.call(this),
+            method: function(value) {
+                var labelEl = this.get('labelEl');
+                if (!labelEl) { // create if needed
+                    this.set('labelEl', _createlabelEl.call(this));
+                }
+                
+                _setLabel.call(this, value);
+            }
+        });
+        
+        /**
+         * The HTMLElement that contains the tab's content.
+         * @config contentEl
+         * @type HTMLElement
+         */
+        this.setAttributeConfig('contentEl', {
+            value: attr.contentEl || document.createElement('div'),
+            method: function(value) {
+                var current = this.get('contentEl');
+
+                if (current) {
+                    if (current == value) {
+                        return false; // already set
+                    }
+                    this.replaceChild(value, current);
+                }
+            }
+        });
+        
+        /**
+         * The tab's content.
+         * @config content
+         * @type String
+         */
+        this.setAttributeConfig('content', {
+            value: attr.content,
+            method: function(value) {
+                this.get('contentEl').innerHTML = value;
+            }
+        });
+
+        var _dataLoaded = false;
+        
+        /**
+         * The tab's data source, used for loading content dynamically.
+         * @config dataSrc
+         * @type String
+         */
+        this.setAttributeConfig('dataSrc', {
+            value: attr.dataSrc
+        });
+        
+        /**
+         * Whether or not content should be reloaded for every view.
+         * @config cacheData
+         * @type Boolean
+         * @default false
+         */
+        this.setAttributeConfig('cacheData', {
+            value: attr.cacheData || false,
+            validator: YAHOO.lang.isBoolean
+        });
+        
+        /**
+         * The method to use for the data request.
+         * @config loadMethod
+         * @type String
+         * @default "GET"
+         */
+        this.setAttributeConfig('loadMethod', {
+            value: attr.loadMethod || 'GET',
+            validator: YAHOO.lang.isString
+        });
+
+        /**
+         * Whether or not any data has been loaded from the server.
+         * @config dataLoaded
+         * @type Boolean
+         */        
+        this.setAttributeConfig('dataLoaded', {
+            value: false,
+            validator: YAHOO.lang.isBoolean,
+            writeOnce: true
+        });
+        
+        /**
+         * Number if milliseconds before aborting and calling failure handler.
+         * @config dataTimeout
+         * @type Number
+         * @default null
+         */
+        this.setAttributeConfig('dataTimeout', {
+            value: attr.dataTimeout || null,
+            validator: YAHOO.lang.isNumber
+        });
+        
+        /**
+         * Whether or not the tab is currently active.
+         * If a dataSrc is set for the tab, the content will be loaded from
+         * the given source.
+         * @config active
+         * @type Boolean
+         */
+        this.setAttributeConfig('active', {
+            value: attr.active || this.hasClass(this.ACTIVE_CLASSNAME),
+            method: function(value) {
+                if (value === true) {
+                    this.addClass(this.ACTIVE_CLASSNAME);
+                    this.set('title', 'active');
+                } else {
+                    this.removeClass(this.ACTIVE_CLASSNAME);
+                    this.set('title', '');
+                }
+            },
+            validator: function(value) {
+                return YAHOO.lang.isBoolean(value) && !this.get('disabled') ;
+            }
+        });
+        
+        /**
+         * Whether or not the tab is disabled.
+         * @config disabled
+         * @type Boolean
+         */
+        this.setAttributeConfig('disabled', {
+            value: attr.disabled || this.hasClass(this.DISABLED_CLASSNAME),
+            method: function(value) {
+                if (value === true) {
+                    Dom.addClass(this.get('element'), this.DISABLED_CLASSNAME);
+                } else {
+                    Dom.removeClass(this.get('element'), this.DISABLED_CLASSNAME);
+                }
+            },
+            validator: YAHOO.lang.isBoolean
+        });
+        
+        /**
+         * The href of the tab's anchor element.
+         * @config href
+         * @type String
+         * @default '#'
+         */
+        this.setAttributeConfig('href', {
+            value: attr.href || '#',
+            method: function(value) {
+                this.getElementsByTagName('a')[0].href = value;
+            },
+            validator: YAHOO.lang.isString
+        });
+        
+        /**
+         * The Whether or not the tab's content is visible.
+         * @config contentVisible
+         * @type Boolean
+         * @default false
+         */
+        this.setAttributeConfig('contentVisible', {
+            value: attr.contentVisible,
+            method: function(value) {
+                if (value) {
+                    this.get('contentEl').style.display = 'block';
+                    
+                    if ( this.get('dataSrc') ) {
+                     // load dynamic content unless already loaded and caching
+                        if ( !this.get('dataLoaded') || !this.get('cacheData') ) {
+                            _dataConnect.call(this);
+                        }
+                    }
+                } else {
+                    this.get('contentEl').style.display = 'none';
+                }
+            },
+            validator: YAHOO.lang.isBoolean
+        });
+    };
+    
+    var _createTabElement = function(attr) {
+        var el = document.createElement('li');
+        var a = document.createElement('a');
+        
+        a.href = attr.href || '#';
+        
+        el.appendChild(a);
+        
+        var label = attr.label || null;
+        var labelEl = attr.labelEl || null;
+        
+        if (labelEl) { // user supplied labelEl
+            if (!label) { // user supplied label
+                label = _getLabel.call(this, labelEl);
+            }
+        } else {
+            labelEl = _createlabelEl.call(this);
+        }
+        
+        a.appendChild(labelEl);
+        
+        return el;
+    };
+    
+    var _getlabelEl = function() {
+        return this.getElementsByTagName(this.LABEL_TAGNAME)[0];
+    };
+    
+    var _createlabelEl = function() {
+        var el = document.createElement(this.LABEL_TAGNAME);
+        return el;
+    };
+    
+    var _setLabel = function(label) {
+        var el = this.get('labelEl');
+        el.innerHTML = label;
+    };
+    
+    var _getLabel = function() {
+        var label,
+            el = this.get('labelEl');
+            
+            if (!el) {
+                return undefined;
+            }
+        
+        return el.innerHTML;
+    };
+    
+    var _dataConnect = function() {
+        if (!YAHOO.util.Connect) {
+            return false;
+        }
+
+        Dom.addClass(this.get('contentEl').parentNode, this.LOADING_CLASSNAME);
+        
+        this.dataConnection = YAHOO.util.Connect.asyncRequest(
+            this.get('loadMethod'),
+            this.get('dataSrc'), 
+            {
+                success: function(o) {
+                    this.loadHandler.success.call(this, o);
+                    this.set('dataLoaded', true);
+                    this.dataConnection = null;
+                    Dom.removeClass(this.get('contentEl').parentNode,
+                            this.LOADING_CLASSNAME);
+                },
+                failure: function(o) {
+                    this.loadHandler.failure.call(this, o);
+                    this.dataConnection = null;
+                    Dom.removeClass(this.get('contentEl').parentNode,
+                            this.LOADING_CLASSNAME);
+                },
+                scope: this,
+                timeout: this.get('dataTimeout')
+            }
+        );
+    };
+    
+    YAHOO.widget.Tab = Tab;
+    
+    /**
+     * Fires before the active state is changed.
+     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+     * <p>If handler returns false, the change will be cancelled, and the value will not
+     * be set.</p>
+     * <p><strong>Event fields:</strong><br>
+     * <code>&lt;String&gt; type</code> beforeActiveChange<br>
+     * <code>&lt;Boolean&gt;
+     * prevValue</code> the current value<br>
+     * <code>&lt;Boolean&gt;
+     * newValue</code> the new value</p>
+     * <p><strong>Usage:</strong><br>
+     * <code>var handler = function(e) {var previous = e.prevValue};<br>
+     * myTabs.addListener('beforeActiveChange', handler);</code></p>
+     * @event beforeActiveChange
+     */
+        
+    /**
+     * Fires after the active state is changed.
+     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+     * <p><strong>Event fields:</strong><br>
+     * <code>&lt;String&gt; type</code> activeChange<br>
+     * <code>&lt;Boolean&gt;
+     * prevValue</code> the previous value<br>
+     * <code>&lt;Boolean&gt;
+     * newValue</code> the updated value</p>
+     * <p><strong>Usage:</strong><br>
+     * <code>var handler = function(e) {var previous = e.prevValue};<br>
+     * myTabs.addListener('activeChange', handler);</code></p>
+     * @event activeChange
+     */
+     
+    /**
+     * Fires before the tab label is changed.
+     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+     * <p>If handler returns false, the change will be cancelled, and the value will not
+     * be set.</p>
+     * <p><strong>Event fields:</strong><br>
+     * <code>&lt;String&gt; type</code> beforeLabelChange<br>
+     * <code>&lt;String&gt;
+     * prevValue</code> the current value<br>
+     * <code>&lt;String&gt;
+     * newValue</code> the new value</p>
+     * <p><strong>Usage:</strong><br>
+     * <code>var handler = function(e) {var previous = e.prevValue};<br>
+     * myTabs.addListener('beforeLabelChange', handler);</code></p>
+     * @event beforeLabelChange
+     */
+        
+    /**
+     * Fires after the tab label is changed.
+     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+     * <p><strong>Event fields:</strong><br>
+     * <code>&lt;String&gt; type</code> labelChange<br>
+     * <code>&lt;String&gt;
+     * prevValue</code> the previous value<br>
+     * <code>&lt;String&gt;
+     * newValue</code> the updated value</p>
+     * <p><strong>Usage:</strong><br>
+     * <code>var handler = function(e) {var previous = e.prevValue};<br>
+     * myTabs.addListener('labelChange', handler);</code></p>
+     * @event labelChange
+     */
+     
+    /**
+     * Fires before the tab content is changed.
+     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+     * <p>If handler returns false, the change will be cancelled, and the value will not
+     * be set.</p>
+     * <p><strong>Event fields:</strong><br>
+     * <code>&lt;String&gt; type</code> beforeContentChange<br>
+     * <code>&lt;String&gt;
+     * prevValue</code> the current value<br>
+     * <code>&lt;String&gt;
+     * newValue</code> the new value</p>
+     * <p><strong>Usage:</strong><br>
+     * <code>var handler = function(e) {var previous = e.prevValue};<br>
+     * myTabs.addListener('beforeContentChange', handler);</code></p>
+     * @event beforeContentChange
+     */
+        
+    /**
+     * Fires after the tab content is changed.
+     * <p>See: <a href="YAHOO.util.Element.html#addListener">Element.addListener</a></p>
+     * <p><strong>Event fields:</strong><br>
+     * <code>&lt;String&gt; type</code> contentChange<br>
+     * <code>&lt;String&gt;
+     * prevValue</code> the previous value<br>
+     * <code>&lt;Boolean&gt;
+     * newValue</code> the updated value</p>
+     * <p><strong>Usage:</strong><br>
+     * <code>var handler = function(e) {var previous = e.prevValue};<br>
+     * myTabs.addListener('contentChange', handler);</code></p>
+     * @event contentChange
+     */
+})();
+
+YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.2.1", build: "193"});

Modified: jifty/branches/virtual-models/share/web/static/js/yui/yahoo.js
==============================================================================
--- jifty/branches/virtual-models/share/web/static/js/yui/yahoo.js	(original)
+++ jifty/branches/virtual-models/share/web/static/js/yui/yahoo.js	Mon May  7 16:28:32 2007
@@ -1,144 +1,442 @@
-/*                                                                                                                                                      
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.12.1
-*/ 
-/**
- * The YAHOO object is the single global object used by YUI Library.  It
- * contains utility function for setting up namespaces, inheritance, and
- * logging.  YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces
- * created automatically for and used by the library.
- * @module yahoo
- * @title  YAHOO Global
- */
-
-if (typeof YAHOO == "undefined") {
-    /**
-     * The YAHOO global namespace object
-     * @class YAHOO
-     * @static
-     */
-    var YAHOO = {};
-}
-
-/**
- * Returns the namespace specified and creates it if it doesn't exist
- * <pre>
- * YAHOO.namespace("property.package");
- * YAHOO.namespace("YAHOO.property.package");
- * </pre>
- * Either of the above would create YAHOO.property, then
- * YAHOO.property.package
- *
- * Be careful when naming packages. Reserved words may work in some browsers
- * and not others. For instance, the following will fail in Safari:
- * <pre>
- * YAHOO.namespace("really.long.nested.namespace");
- * </pre>
- * This fails because "long" is a future reserved word in ECMAScript
- *
- * @method namespace
- * @static
- * @param  {String*} arguments 1-n namespaces to create 
- * @return {Object}  A reference to the last namespace object created
- */
-YAHOO.namespace = function() {
-    var a=arguments, o=null, i, j, d;
-    for (i=0; i<a.length; ++i) {
-        d=a[i].split(".");
-        o=YAHOO;
-
-        // YAHOO is implied, so it is ignored if it is included
-        for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; ++j) {
-            o[d[j]]=o[d[j]] || {};
-            o=o[d[j]];
-        }
-    }
-
-    return o;
-};
-
-/**
- * Uses YAHOO.widget.Logger to output a log message, if the widget is available.
- *
- * @method log
- * @static
- * @param  {String}  msg  The message to log.
- * @param  {String}  cat  The log category for the message.  Default
- *                        categories are "info", "warn", "error", time".
- *                        Custom categories can be used as well. (opt)
- * @param  {String}  src  The source of the the message (opt)
- * @return {Boolean}      True if the log operation was successful.
- */
-YAHOO.log = function(msg, cat, src) {
-    var l=YAHOO.widget.Logger;
-    if(l && l.log) {
-        return l.log(msg, cat, src);
-    } else {
-        return false;
-    }
-};
-
-/**
- * Utility to set up the prototype, constructor and superclass properties to
- * support an inheritance strategy that can chain constructors and methods.
- *
- * @method extend
- * @static
- * @param {Function} subc   the object to modify
- * @param {Function} superc the object to inherit
- * @param {Object} overrides  additional properties/methods to add to the
- *                              subclass prototype.  These will override the
- *                              matching items obtained from the superclass 
- *                              if present.
- */
-YAHOO.extend = function(subc, superc, overrides) {
-    var F = function() {};
-    F.prototype=superc.prototype;
-    subc.prototype=new F();
-    subc.prototype.constructor=subc;
-    subc.superclass=superc.prototype;
-    if (superc.prototype.constructor == Object.prototype.constructor) {
-        superc.prototype.constructor=superc;
-    }
-
-    if (overrides) {
-        for (var i in overrides) {
-            subc.prototype[i]=overrides[i];
-        }
-    }
-};
-
-/**
- * Applies all prototype properties in the supplier to the receiver if the
- * receiver does not have these properties yet.  Optionally, one or more
- * methods/properties can be specified (as additional parameters).  This
- * option will overwrite the property if receiver has it already.
- *
- * @method augment
- * @static
- * @param {Function} r  the object to receive the augmentation
- * @param {Function} s  the object that supplies the properties to augment
- * @param {String*}  arguments zero or more properties methods to augment the
- *                             receiver with.  If none specified, everything
- *                             in the supplier will be used unless it would
- *                             overwrite an existing property in the receiver
- */
-YAHOO.augment = function(r, s) {
-    var rp=r.prototype, sp=s.prototype, a=arguments, i, p;
-    if (a[2]) {
-        for (i=2; i<a.length; ++i) {
-            rp[a[i]] = sp[a[i]];
-        }
-    } else {
-        for (p in sp) { 
-            if (!rp[p]) {
-                rp[p] = sp[p];
-            }
-        }
-    }
-};
-
-YAHOO.namespace("util", "widget", "example");
-
+/*
+Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.2.1
+*/
+/**
+ * The YAHOO object is the single global object used by YUI Library.  It
+ * contains utility function for setting up namespaces, inheritance, and
+ * logging.  YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces
+ * created automatically for and used by the library.
+ * @module yahoo
+ * @title  YAHOO Global
+ */
+
+/**
+ * YAHOO_config is not included part of the library.  Instead it is an object
+ * that can be defined by the implementer immediately before including the
+ * YUI library.  The properties included in this object will be used to
+ * configure global properties needed as soon as the library begins to load.
+ * @class YAHOO_config
+ * @static
+ */
+
+/**
+ * A reference to a function that will be executed every time a YAHOO module
+ * is loaded.  As parameter, this function will receive the version
+ * information for the module. See <a href="YAHOO.env.html#getVersion">
+ * YAHOO.env.getVersion</a> for the description of the version data structure.
+ * @property listener
+ * @static
+ */
+if (typeof YAHOO == "undefined") {
+    /**
+     * The YAHOO global namespace object.  If YAHOO is already defined, the
+     * existing YAHOO object will not be overwritten so that defined
+     * namespaces are preserved.
+     * @class YAHOO
+     * @static
+     */
+    var YAHOO = {};
+}
+
+/**
+ * Returns the namespace specified and creates it if it doesn't exist
+ * <pre>
+ * YAHOO.namespace("property.package");
+ * YAHOO.namespace("YAHOO.property.package");
+ * </pre>
+ * Either of the above would create YAHOO.property, then
+ * YAHOO.property.package
+ *
+ * Be careful when naming packages. Reserved words may work in some browsers
+ * and not others. For instance, the following will fail in Safari:
+ * <pre>
+ * YAHOO.namespace("really.long.nested.namespace");
+ * </pre>
+ * This fails because "long" is a future reserved word in ECMAScript
+ *
+ * @method namespace
+ * @static
+ * @param  {String*} arguments 1-n namespaces to create 
+ * @return {Object}  A reference to the last namespace object created
+ */
+YAHOO.namespace = function() {
+    var a=arguments, o=null, i, j, d;
+    for (i=0; i<a.length; i=i+1) {
+        d=a[i].split(".");
+        o=YAHOO;
+
+        // YAHOO is implied, so it is ignored if it is included
+        for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
+            o[d[j]]=o[d[j]] || {};
+            o=o[d[j]];
+        }
+    }
+
+    return o;
+};
+
+/**
+ * Uses YAHOO.widget.Logger to output a log message, if the widget is
+ * available.
+ *
+ * @method log
+ * @static
+ * @param  {String}  msg  The message to log.
+ * @param  {String}  cat  The log category for the message.  Default
+ *                        categories are "info", "warn", "error", time".
+ *                        Custom categories can be used as well. (opt)
+ * @param  {String}  src  The source of the the message (opt)
+ * @return {Boolean}      True if the log operation was successful.
+ */
+YAHOO.log = function(msg, cat, src) {
+    var l=YAHOO.widget.Logger;
+    if(l && l.log) {
+        return l.log(msg, cat, src);
+    } else {
+        return false;
+    }
+};
+
+
+/**
+ * Initializes the global by creating the default namespaces and applying
+ * any new configuration information that is detected.
+ * @method init
+ * @static
+ */
+YAHOO.init = function() {
+    this.namespace("util", "widget", "example");
+    if (typeof YAHOO_config != "undefined") {
+        var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i;
+        if (l) {
+            // if YAHOO is loaded multiple times we need to check to see if
+            // this is a new config object.  If it is, add the new component
+            // load listener to the stack
+            for (i=0;i<ls.length;i=i+1) {
+                if (ls[i]==l) {
+                    unique=false;
+                    break;
+                }
+            }
+            if (unique) {
+                ls.push(l);
+            }
+        }
+    }
+};
+
+/**
+ * Registers a module with the YAHOO object
+ * @method register
+ * @static
+ * @param {String}   name    the name of the module (event, slider, etc)
+ * @param {Function} mainClass a reference to class in the module.  This
+ *                             class will be tagged with the version info
+ *                             so that it will be possible to identify the
+ *                             version that is in use when multiple versions
+ *                             have loaded
+ * @param {Object}   data      metadata object for the module.  Currently it
+ *                             is expected to contain a "version" property
+ *                             and a "build" property at minimum.
+ */
+YAHOO.register = function(name, mainClass, data) {
+    var mods = YAHOO.env.modules;
+    if (!mods[name]) {
+        mods[name] = { versions:[], builds:[] };
+    }
+    var m=mods[name],v=data.version,b=data.build,ls=YAHOO.env.listeners;
+    m.name = name;
+    m.version = v;
+    m.build = b;
+    m.versions.push(v);
+    m.builds.push(b);
+    m.mainClass = mainClass;
+    // fire the module load listeners
+    for (var i=0;i<ls.length;i=i+1) {
+        ls[i](m);
+    }
+    // label the main class
+    if (mainClass) {
+        mainClass.VERSION = v;
+        mainClass.BUILD = b;
+    } else {
+        YAHOO.log("mainClass is undefined for module " + name, "warn");
+    }
+};
+
+/**
+ * YAHOO.env is used to keep track of what is known about the YUI library and
+ * the browsing environment
+ * @class YAHOO.env
+ * @type Object
+ * @static
+ */
+YAHOO.env = YAHOO.env || {
+    /**
+     * Keeps the version info for all YUI modules that have reported themselves
+     * @property modules
+     * @type Object[]
+     */
+    modules: [],
+    
+    /**
+     * List of functions that should be executed every time a YUI module
+     * reports itself.
+     * @property listeners
+     * @type Function[]
+     */
+    listeners: [],
+    
+    /**
+     * Returns the version data for the specified module:
+     *      <dl>
+     *      <dt>name:</dt>      <dd>The name of the module</dd>
+     *      <dt>version:</dt>   <dd>The version in use</dd>
+     *      <dt>build:</dt>     <dd>The build number in use</dd>
+     *      <dt>versions:</dt>  <dd>All versions that were registered</dd>
+     *      <dt>builds:</dt>    <dd>All builds that were registered.</dd>
+     *      <dt>mainClass:</dt> <dd>An object that was was stamped with the
+     *                 current version and build. If 
+     *                 mainClass.VERSION != version or mainClass.BUILD != build,
+     *                 multiple versions of pieces of the library have been
+     *                 loaded, potentially causing issues.</dd>
+     *       </dl>
+     *
+     * @method getVersion
+     * @static
+     * @param {String}  name the name of the module (event, slider, etc)
+     * @return {Object} The version info
+     */
+    getVersion: function(name) {
+        return YAHOO.env.modules[name] || null;
+    }
+};
+
+/**
+ * Provides the language utilites and extensions used by the library
+ * @class YAHOO.lang
+ */
+YAHOO.lang = {
+    /**
+     * Determines whether or not the provided object is an array
+     * @method isArray
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isArray: function(obj) { // frames lose type, so test constructor string
+        if (obj && obj.constructor && 
+                   obj.constructor.toString().indexOf('Array') > -1) {
+            return true;
+        } else {
+            return YAHOO.lang.isObject(obj) && obj.constructor == Array;
+        }
+    },
+
+    /**
+     * Determines whether or not the provided object is a boolean
+     * @method isBoolean
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isBoolean: function(obj) {
+        return typeof obj == 'boolean';
+    },
+    
+    /**
+     * Determines whether or not the provided object is a function
+     * @method isFunction
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isFunction: function(obj) {
+        return typeof obj == 'function';
+    },
+        
+    /**
+     * Determines whether or not the provided object is null
+     * @method isNull
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isNull: function(obj) {
+        return obj === null;
+    },
+        
+    /**
+     * Determines whether or not the provided object is a legal number
+     * @method isNumber
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isNumber: function(obj) {
+        return typeof obj == 'number' && isFinite(obj);
+    },
+      
+    /**
+     * Determines whether or not the provided object is of type object
+     * or function
+     * @method isObject
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */  
+    isObject: function(obj) {
+        return obj && (typeof obj == 'object' || YAHOO.lang.isFunction(obj));
+    },
+        
+    /**
+     * Determines whether or not the provided object is a string
+     * @method isString
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isString: function(obj) {
+        return typeof obj == 'string';
+    },
+        
+    /**
+     * Determines whether or not the provided object is undefined
+     * @method isUndefined
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    isUndefined: function(obj) {
+        return typeof obj == 'undefined';
+    },
+    
+    /**
+     * Determines whether or not the property was added
+     * to the object instance.  Returns false if the property is not present
+     * in the object, or was inherited from the prototype.
+     * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x.
+     * There is a discrepancy between YAHOO.lang.hasOwnProperty and
+     * Object.prototype.hasOwnProperty when the property is a primitive added to
+     * both the instance AND prototype with the same value:
+     * <pre>
+     * var A = function() {};
+     * A.prototype.foo = 'foo';
+     * var a = new A();
+     * a.foo = 'foo';
+     * alert(a.hasOwnProperty('foo')); // true
+     * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback
+     * </pre>
+     * @method hasOwnProperty
+     * @param {any} obj The object being testing
+     * @return Boolean
+     */
+    hasOwnProperty: function(obj, prop) {
+        if (Object.prototype.hasOwnProperty) {
+            return obj.hasOwnProperty(prop);
+        }
+        
+        return !YAHOO.lang.isUndefined(obj[prop]) && 
+                obj.constructor.prototype[prop] !== obj[prop];
+    },
+        
+    /**
+     * Utility to set up the prototype, constructor and superclass properties to
+     * support an inheritance strategy that can chain constructors and methods.
+     *
+     * @method extend
+     * @static
+     * @param {Function} subc   the object to modify
+     * @param {Function} superc the object to inherit
+     * @param {Object} overrides  additional properties/methods to add to the
+     *                              subclass prototype.  These will override the
+     *                              matching items obtained from the superclass 
+     *                              if present.
+     */
+    extend: function(subc, superc, overrides) {
+        if (!superc||!subc) {
+            throw new Error("YAHOO.lang.extend failed, please check that " +
+                            "all dependencies are included.");
+        }
+        var F = function() {};
+        F.prototype=superc.prototype;
+        subc.prototype=new F();
+        subc.prototype.constructor=subc;
+        subc.superclass=superc.prototype;
+        if (superc.prototype.constructor == Object.prototype.constructor) {
+            superc.prototype.constructor=superc;
+        }
+    
+        if (overrides) {
+            for (var i in overrides) {
+                subc.prototype[i]=overrides[i];
+            }
+        }
+    },
+    
+    /**
+     * Applies all prototype properties in the supplier to the receiver if the
+     * receiver does not have these properties yet.  Optionally, one or more
+     * methods/properties can be specified (as additional parameters).  This
+     * option will overwrite the property if receiver has it already.
+     *
+     * @method augment
+     * @static
+     * @param {Function} r  the object to receive the augmentation
+     * @param {Function} s  the object that supplies the properties to augment
+     * @param {String*}  arguments zero or more properties methods to augment the
+     *                             receiver with.  If none specified, everything
+     *                             in the supplier will be used unless it would
+     *                             overwrite an existing property in the receiver
+     */
+    augment: function(r, s) {
+        if (!s||!r) {
+            throw new Error("YAHOO.lang.augment failed, please check that " +
+                            "all dependencies are included.");
+        }
+        var rp=r.prototype, sp=s.prototype, a=arguments, i, p;
+        if (a[2]) {
+            for (i=2; i<a.length; i=i+1) {
+                rp[a[i]] = sp[a[i]];
+            }
+        } else {
+            for (p in sp) { 
+                if (!rp[p]) {
+                    rp[p] = sp[p];
+                }
+            }
+        }
+    }
+};
+
+YAHOO.init();
+
+/*
+ * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a>
+ * @class YAHOO.util.Lang
+ */
+YAHOO.util.Lang = YAHOO.lang;
+
+/**
+ * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a>
+ * @for YAHOO
+ * @method augment
+ * @static
+ * @param {Function} r  the object to receive the augmentation
+ * @param {Function} s  the object that supplies the properties to augment
+ * @param {String*}  arguments zero or more properties methods to augment the
+ *                             receiver with.  If none specified, everything
+ *                             in the supplier will be used unless it would
+ *                             overwrite an existing property in the receiver
+ */
+YAHOO.augment = YAHOO.lang.augment;
+       
+/**
+ * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a>
+ * @method extend
+ * @static
+ * @param {Function} subc   the object to modify
+ * @param {Function} superc the object to inherit
+ * @param {Object} overrides  additional properties/methods to add to the
+ *                              subclass prototype.  These will override the
+ *                              matching items obtained from the superclass 
+ *                              if present.
+ */
+YAHOO.extend = YAHOO.lang.extend;
+
+YAHOO.register("yahoo", YAHOO, {version: "2.2.1", build: "193"});

Modified: jifty/branches/virtual-models/share/web/templates/_elements/nav
==============================================================================
--- jifty/branches/virtual-models/share/web/templates/_elements/nav	(original)
+++ jifty/branches/virtual-models/share/web/templates/_elements/nav	Mon May  7 16:28:32 2007
@@ -1,9 +1,2 @@
-<%init>
-my $top = Jifty->web->navigation;
-$top->child(Home       => label => _('Home'), url => "/", sort_order => 1);
- if (Jifty->config->framework('AdminMode') ) {
-    $top->child(Administration       => url => "/__jifty/admin/", label => _('Administration'), sort_order => 998);
-    $top->child(OnlineDocs       => url => "/__jifty/online_docs/", label => _('Online docs'),  sort_order => 999);
- }
-return();
-</%init>
+%# Navigation frobbing now handled in Dispatcher plugins
+%# This exists for backwards compatibility 

Added: jifty/branches/virtual-models/t/01-test-mechanize.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/01-test-mechanize.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,18 @@
+use warnings;
+use strict;
+
+use Jifty::Test tests => 6;
+
+use_ok('Jifty::Test::WWW::Mechanize');
+
+my $server = Jifty::Test->make_server;
+my $url = $server->started_ok;
+
+my $mech = Jifty::Test::WWW::Mechanize->new;
+ok($mech, 'contructed Jifty::Test::WWW::Mechanize');
+isa_ok($mech, 'Jifty::Test::WWW::Mechanize');
+isa_ok($mech, 'Test::WWW::Mechanize');
+isa_ok($mech, 'WWW::Mechanize');
+
+# XXX TODO need more tests to make sure that our mech can connect
+# and do meaningful tests on a Jifty server

Added: jifty/branches/virtual-models/t/10-utf8.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/10-utf8.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More tests => 3;
+
+use Jifty::Everything;
+
+# test that various parts of jifty work with UTF-8 in the right way
+
+diag "escape_uri" if $ENV{TEST_VERBOSE};
+{
+    my $s = 'a';
+    Jifty::View::Mason::Handler::escape_uri(\$s);
+    is $s, 'a', 'ASCII';
+    $s = "\x{E9}";
+    Jifty::View::Mason::Handler::escape_uri(\$s);
+    is $s, '%C3%A9', 'latin small letter e with accute';
+    $s = "\x{435}";
+    Jifty::View::Mason::Handler::escape_uri(\$s);
+    is $s, '%D0%B5', 'russian small letter e';
+}
+

Modified: jifty/branches/virtual-models/t/Mapper/t/02-api.t
==============================================================================
--- jifty/branches/virtual-models/t/Mapper/t/02-api.t	(original)
+++ jifty/branches/virtual-models/t/Mapper/t/02-api.t	Mon May  7 16:28:32 2007
@@ -33,13 +33,13 @@
 # Feeding the first action into the second should cause both to run;
 # first, test via setting arguments during action creation (which sets
 # sticky values)
-$mech->form(2);
+$mech->form_number(2);
 ok($mech->click_button(value => "Do both"));
 $mech->content_like(qr/got the grail/i, "Got the grail");
 $mech->content_like(qr/crossed the bridge/i, "And crossed the bridge");
 
 # And then, the same, but via default_values on the form field
-$mech->form(3);
+$mech->form_number(3);
 ok($mech->click_button(value => "Do both"));
 $mech->content_like(qr/got the grail/i, "Got the grail");
 $mech->content_like(qr/crossed the bridge/i, "And crossed the bridge");

Modified: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/etc/config.yml
==============================================================================
--- jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/etc/config.yml	(original)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/etc/config.yml	Mon May  7 16:28:32 2007
@@ -22,7 +22,6 @@
     - %log/mail.log%
 
   Plugins: 
-    - User: {}
     - Authentication::Password: {}
     - 
       REST: {}

Added: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/CurrentUser.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/CurrentUser.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,30 @@
+package TestApp::Plugin::PasswordAuth::CurrentUser;
+
+use strict;
+use warnings;
+
+use base qw(Jifty::CurrentUser);
+
+__PACKAGE__->mk_accessors(qw(group));
+
+sub _init {
+   my $self = shift;
+   my %args = (@_);
+
+   if (delete $args{'_bootstrap'} ) {
+       $self->is_bootstrap_user(1);
+   } elsif (keys %args) {
+       $self->user_object(TestApp::Plugin::PasswordAuth::Model::User->new(current_user => $self));
+       $self->user_object->load_by_cols(%args);
+
+       if ( $self->user_object->mygroup eq 'admin') {
+           $self->is_superuser(1);
+       };
+
+       $self->group($self->user_object->mygroup);
+   };
+   $self->SUPER::_init(%args);
+};
+
+
+1;

Modified: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Dispatcher.pm	Mon May  7 16:28:32 2007
@@ -1,7 +1,12 @@
-use strict;
-use warnings;
 package TestApp::Plugin::PasswordAuth::Dispatcher;
 use Jifty::Dispatcher -base;
 
+on qr{/setuser/(.*)} => run {
+    my $name = $1;
+
+    my $current_user = TestApp::Plugin::PasswordAuth::CurrentUser->new( name => $name );
+    Jifty->web->current_user( $current_user );
+    show '/index.html';
+};
 
 1;

Modified: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model/User.pm
==============================================================================
--- jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model/User.pm	(original)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/lib/TestApp/Plugin/PasswordAuth/Model/User.pm	Mon May  7 16:28:32 2007
@@ -7,6 +7,9 @@
 # Mixins
 
 use TestApp::Plugin::PasswordAuth::Record schema {
+   column 'mygroup' =>
+             valid_values are qw/admin moderator user/,
+             default is 'user';
 
 };
 
@@ -17,5 +20,9 @@
 
 # Your model-specific methods go here.
 
+sub current_user_can {
+    return 1;
+};
+
 1;
 

Modified: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/00-model-User.t
==============================================================================
--- jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/00-model-User.t	(original)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/00-model-User.t	Mon May  7 16:28:32 2007
@@ -7,10 +7,11 @@
 A basic test harness for the User model.
 
 =cut
+
 use lib 't/lib';
 use Jifty::SubTest;
 
-use Jifty::Test tests => 15;
+use Jifty::Test tests => 17;
 
 # Make sure we can load the model
 use_ok('TestApp::Plugin::PasswordAuth::Model::User');
@@ -39,6 +40,9 @@
 is($o->color, 'gray');
 is ($o->swallow_type, 'african');
 
+can_ok($o, 'mygroup');
+is ($o->mygroup, 'user', 'Default user is in group user');
+
 
 my $p = TestApp::Plugin::PasswordAuth::Model::User->new(current_user => $system_user);
  ($id) = $p->create( name => 'jesse2',

Added: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/11-current_user.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/11-current_user.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,56 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+=head1 DESCRIPTION
+
+Basic tests for CurrentUser.
+
+=cut
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test tests => 14;
+#use Jifty::Test::WWW::Mechanize;
+
+use_ok('TestApp::Plugin::PasswordAuth::Model::User');
+use_ok('TestApp::Plugin::PasswordAuth::CurrentUser');
+
+# Get a system user
+my $system_user = TestApp::Plugin::PasswordAuth::CurrentUser->superuser;
+ok($system_user, "Found a system user");
+
+# Create two users
+my $o = TestApp::Plugin::PasswordAuth::Model::User->new(current_user => $system_user);
+$o->create( name => 'A User', email => 'auser at example.com', swallow_type => 'african',
+            password => 'secret' );
+ok($o->id, "New user has valid id set");
+is($o->mygroup, 'user', "User is not admin");
+$o->create( name => 'Bob', email => 'bob at example.com', swallow_type => 'african', 
+            password => 'secret2', mygroup => 'admin' );
+ok($o->id, "New user has valid id set");
+is($o->mygroup, 'admin', "User is admin");
+
+# Create a CurrentUser
+my $bob = TestApp::Plugin::PasswordAuth::CurrentUser->new( name => 'Bob' );
+ok($bob->id, "CurrentUser has a valid id set");
+is($bob->id, $o->id, "The ids match");
+is($bob->user_object->name, 'Bob', "The CurrentUser is Bob");
+is($bob->user_object->email, 'bob at example.com', 'The CurrentUser email is bob at example.com');
+is($bob->user_object->swallow_type, 'african', "The CurrentUser swallow_type is african");
+is($bob->user_object->mygroup, 'admin', "The CurrentUser group is admin");
+ok($bob->is_superuser, "CurrentUser is a superuser");
+
+#my $server = Jifty::Test->make_server;
+#isa_ok($server, 'Jifty::Server');
+
+#my $URL = $server->started_ok;
+#my $mech = Jifty::Test::WWW::Mechanize->new();
+
+#$mech->get_ok("$URL/currentuser", "Got currentuser page");
+#$mech->content_contains("No current user set.", "Good, no current user yet");
+#$mech->get_ok("$URL/setuser/Bob", "Setting currentuser to Bob");
+#$mech->get_ok("$URL/currentuser", "Refetched currentuser page");
+#$mech->content_contains("Current user is Bob", "Now the current_user is set");
+#$mech->content_contains("The current user is a superuser", "... and the current_user is a superuser");

Added: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/12-i18n.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/12-i18n.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,52 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+=head1 DESCRIPTION
+
+Basic tests for I18N.
+
+=cut
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test tests => 7;
+use Jifty::Test::WWW::Mechanize;
+
+use Encode 'decode';
+use utf8;
+use LWP::UserAgent;
+
+
+my $server = Jifty::Test->make_server;
+isa_ok($server, 'Jifty::Server');
+
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new();
+
+$mech->get_ok("$URL/login","Got login page");
+
+my $ua = LWP::UserAgent->new;
+my $res;
+
+$ua->default_header('Accept-Language' => "en");
+$res = $ua->get("$URL/login");
+ok $res->is_success, "can access login page";
+like $res->content, qr/Lost your password/, 'en works';
+
+$ua->default_header('Accept-Language' => "fr");
+$res = $ua->get("$URL/login");
+ok $res->is_success, "can access login page";
+like adjust($res->content), qr/oublié/,'fr login works';
+
+sub adjust {
+    my $s = shift;
+    $s = decode('UTF-8', $s);
+    $s =~ s/<.*?>//gs;
+    $s =~ s/\s+/ /gs;
+    #$s =~ s/\W+//g;
+    #$s =~ s/\d+//g;
+    $s;
+}
+

Added: jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/12-signup.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-PasswordAuth/t/12-signup.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,34 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+
+=head1 DESCRIPTION
+
+Regression test - ensure /signup provides the signup form
+
+=cut
+
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test tests => 5;
+use Jifty::Test::WWW::Mechanize;
+
+my $server  = Jifty::Test->make_server;
+
+isa_ok($server, 'Jifty::Server');
+
+my $URL     = $server->started_ok;
+my $mech    = Jifty::Test::WWW::Mechanize->new();
+ok(1, "Loaded the test script");
+
+my $signup_page = "$URL/signup";
+$mech->get_ok($signup_page, "signup page exists");
+
+use Data::Dumper;
+ok ( $mech->moniker_for('TestApp::Plugin::PasswordAuth::Action::Signup'),
+     'signup page includes the signup form');
+
+1;

Modified: jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm
==============================================================================
--- jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm	(original)
+++ jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm	Mon May  7 16:28:32 2007
@@ -35,4 +35,17 @@
     outs('/path_test/td_only - T::D');
 };
 
+
+# for testing subclasses
+template 'entry.html' => sub {
+    my $self = shift;
+    outs("/entry.html=$self")
+};
+
+require TestApp::View::base;
+require TestApp::View::instance;
+import_templates TestApp::View::base under '/base';
+import_templates TestApp::View::instance under '/instance';
+
+
 1;

Added: jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/base.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/base.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,33 @@
+package TestApp::View::base;
+use Jifty::View::Declare -base;
+
+template 'list_ht' => sub {
+    my $self = shift;
+    outs("/base/list=$self");
+    for (0..1) {
+	$self->has_template('view')->();
+    }
+};
+
+template 'list_s' => sub {
+    my $self = shift;
+    outs("/base/list=$self");
+    for (0..1) {
+	show('view');
+    }
+};
+
+template 'list_rg' => sub {
+    my $self = shift;
+    outs("/base/list=$self");
+    for (0..1) {
+	render_region('view-'.$_, path => 'view');
+    }
+};
+
+template 'view' => sub {
+    my $self = shift;
+    outs("/base/view=$self");
+};
+
+1;

Added: jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/instance.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp/lib/TestApp/View/instance.pm	Mon May  7 16:28:32 2007
@@ -0,0 +1,14 @@
+package TestApp::View::instance;
+use Jifty::View::Declare -base;
+use base 'TestApp::View::base';
+
+template 'myview' => sub {
+    
+};
+
+template 'view' => sub {
+    my $self = shift;
+    outs("/instance/view=$self");
+};
+
+1;

Added: jifty/branches/virtual-models/t/TestApp/t/15-template-subclass.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp/t/15-template-subclass.t	Mon May  7 16:28:32 2007
@@ -0,0 +1,85 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test;
+use Jifty::Test::WWW::Mechanize;
+
+my @tests = (
+    {
+        url  => "/entry.html",
+        text => '/entry.html=TestApp::View',
+    },
+    {
+        url  => "/base/list_s",
+        text => '/base/list=TestApp::View::base'.
+		'/base/view=TestApp::View::base'.
+		'/base/view=TestApp::View::base'
+    },
+    {
+        url  => "/base/list_ht",
+        text => '/base/list=TestApp::View::base'.
+		'/base/view=TestApp::View::base'.
+		'/base/view=TestApp::View::base'
+    },
+    {
+        url  => "/base/list_rg",
+        text => '/base/list=TestApp::View::base'.
+                in_region('view-0', '/base/view', '/base/view=TestApp::View::base').
+                in_region('view-1', '/base/view', '/base/view=TestApp::View::base')
+    },
+
+
+    # instance
+    {
+        url  => "/instance/list_s",
+        text => '/base/list=TestApp::View::instance'.
+		'/instance/view=TestApp::View::instance'.
+		'/instance/view=TestApp::View::instance'
+    },
+    {
+        url  => "/instance/list_ht",
+        text => '/base/list=TestApp::View::instance'.
+		'/instance/view=TestApp::View::instance'.
+		'/instance/view=TestApp::View::instance'
+    },
+    {
+        url  => "/instance/list_rg",
+        text => '/base/list=TestApp::View::instance'.
+                in_region('view-0', '/instance/view', '/instance/view=TestApp::View::instance').
+                in_region('view-1', '/instance/view', '/instance/view=TestApp::View::instance')
+    },
+
+
+);
+
+sub in_region {
+    qq|<script type="text/javascript">
+new Region('$_[0]',{},'$_[1]',null);
+</script><div id="region-$_[0]">$_[2]</div>|;
+}
+
+plan tests => 2 + scalar(@tests) * 2;
+
+my $server = Jifty::Test->make_server;
+isa_ok( $server, 'Jifty::Server' );
+my $URL = $server->started_ok;
+
+
+my $mech = Jifty::Test::WWW::Mechanize->new;
+foreach my $test (@tests) {
+    $mech->get_ok( $URL . $test->{url}, "get '$URL: /jifty/jifty/trunk/t/TestApp/t/15-template-subclass.t $test->{url}'" );
+    TODO: { 
+
+    local $TODO = " Template subclassing needs some love";
+    ok($mech->content =~ qr{$test->{text}}, "found the test content");
+    # $mech->content_contains breaks on multiline content
+    #$mech->content_contains( $test->{text}, "found content '$test->{text}'" );
+    };
+
+}
+
+1;


More information about the Jifty-commit mailing list